四、使用 OAuth2 保护 Web API
本章解释了如何使用 OAuth2 来保护一个 web API,通过使用 OWIN 中间件对成员数据库进行认证。 您将能够使用本地登录使用 OAuth2 发送经过认证的请求。
在本章中,我们将涵盖以下主题:
- 在 IIS 中托管 OWIN 并将 Web API 添加到 OWIN 管道中
- 个人用户帐户登录认证流程
- 发送未经授权的请求
- 获取访问令牌
- 发送经过验证的请求
在 IIS 中托管 OWIN,并向 OWIN 管道中添加 Web API
让我们创建一个空的 Web API 模板来集成 ASP。 净的身份。 遵循以下步骤:
- 在 Visual Studio 的Start页面中创建新项目。
- 选择 Visual c# Installed Template 命名为Web。
- 选择ASP.NET Web 应用。
-
Name the project
ContactLookupOwin
and click OK:图 1 -我们已经命名了 ASP.NET Web 应用作为“ContactLookupOwin”
-
Select the Empty template in the New ASP.NET Project dialog and click OK:
图 2 -为应用“ContactLookupOwin”选择空模板
-
Install NuGet packages for the OWIN server that enables OWIN-based applications to run on IIS using the ASP.NET request pipeline:
图 3 -已安装的 NuGet 包“microsoft . owen . host . systemweb”
-
Right-click on Project and select Add New Item in the
ContactLookupOwin
project. Then, select the OWIN startup class in the center pane and name the class fileOwinStartup.cs
:图 4 -添加了名为“OwinStartup.cs”的 OWIN 启动类文件
-
用以下代码替换
OwinStartup
类中的Configuration
方法:
这段代码配置响应的内容类型,写入响应体。 当服务器接收到 HTTP 请求时,OWIN 管道会调用中间件。
通过按F5运行应用,您将在浏览器中看到以下输出:
图 5 -响应注入内容“Owin Startup”
按照给出的步骤将 Web API 添加到 OWIN 管道:
-
在包管理控制台运行如下命令安装 NuGet 包
Microsoft.AspNet.WebApi.OwinSelfHost
:Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
-
这个包使应用能够托管 ASP.NET Web API 在我们的进程中使用 OWIN HttpListener 服务器。
-
修改
Owin Startup
类中的Configuration
方法,代码如下:``` public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
app.UseWebApi(config); app.Run(context => { context.Response.ContentType = "text/plain"; return context.Response.WriteAsync("Owin Startup."); });
} ```
-
添加一个名为
ContactsController
和继承自ApiController
的新类文件,如下所示: -
Run the application by pressing F5 and go to
http://localhost:55781/api/contacts
in a browser, as shown in the following screenshot:图 6 - Contacts Web API 控制器返回 JSON 格式的联系人列表
-
请注意我们已经成功地将 Web API 添加到 OWIN 管道中,并且运行了它。
个人用户账号认证流程
Web API 中的个人用户登录使用 OAuth2 来使用资源所有者密码流对请求进行认证。 资源所有者密码流是 OAuth2 中定义的一个大类型。 此认证流使客户机能够向授权服务器发送用户名和密码。 本地登录的基本流程如下所示:
- 最终用户在客户端屏幕上提供用户名和密码。
- 客户端将用户名和密码发送给服务器,服务器返回一个访问令牌。
- 服务器验证接收到的用户名和密码,并返回一个访问令牌。
- 客户端通过在Authorization报头中发送 HTTP 请求并发送访问令牌来访问受保护的资源。
下图展示了 OAuth2 认证的基本流程:
图 7 -资源所有者密码流程
下图显示了在 ASP 中认证过程。 净 Web API。 Web API 中的授权服务器负责对请求进行认证并发出令牌。 在这里,资源服务器是 Web API 控制器。 因此,为了保护 Web API 控制器免受未经授权的访问,我们需要用[Authorize]属性装饰这些控制器。 如果控制器或动作带有[Authorize]属性,则必须对请求进行认证。 如果请求没有经过认证,那么 Web API 将返回 401 (Unauthorized)错误,因为授权被拒绝了:
图 8 - Web API 认证流程
发送未经授权的请求
为了查看向 Web API 控制器发送未经授权的请求的结果,该控制器被装饰为带有 Authorize 属性,让我们按照给定的步骤创建一个 Web API:
- 在 Visual Studio 的Start页面中创建新项目。
- 选择 Visual c# Installed Template 命名为Web。
- 选择ASP.NET Web 应用。
-
Name the project
WebAPIWithAuthorize
and click OK:图 9 -我们已经命名了 ASP.NET Web 应用作为“WebAPIWithAuthorize”
-
在中选择Web API模板.NET 项目对话框。 这将在Add folders and core references下默认选择Web API和MVC。
-
Click OK to create the application, leaving Authentication as Individual User Accounts by default:
图 10 -我们选择了 Web API
所创建的 Web API 项目包含一个名为HomeController
的 MVC 控制器和两个 Web API 控制器,即AccountController
和ValuesController
。 AccountController
处理用户账号的注册、登录、注销、密码修改等操作。 是一个具有一些基本操作的 Web API 控制器,例如插图。 您会注意到这个控制器是用[Authorize]
属性装饰的。 所以只有经过认证的请求才能访问这个控制器:
[Authorize]
public class ValuesController : ApiController
{
...
}
让我们运行应用并浏览 URLhttp://localhost:61486/api/Values/
。 您将得到以下授权错误:
图 11 -发生非法访问错误
我还为您使用 Fiddler 捕获了这个操作的请求和响应,如下所示:
GET http://localhost:61486/api/Values HTTP/1.1
Host: localhost:61486
我收到的回复如下:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Bearer
X-Powered-By: ASP.NET
Date: Sun, 09 Aug 2015 09:14:21 GMT
Content-Length: 61
{"Message":"Authorization has been denied for this request."}
正如您在响应正文中收到的消息中所看到的,请求已被拒绝,因为它没有经过认证,并且响应返回 401 HTTP 状态码。 发生这种情况是因为请求中缺少 Authorization 头,因为没有承载令牌。
获取访问令牌
要将经过验证的请求发送给ValuesController
,我们需要在 Authorization 报头中传递一个访问令牌。 我们如何得到这个访问令牌? 要获得这个访问令牌,我们需要登录应用。
让我们首先通过在 Account 控制器的 Web API register 操作方法中发布一个用户实例来注册一个用户,如下所示:
图 12 -发布一个 User 实例到 Web API
现在,我们有一个注册用户,用户名steve@jobs.com
和密码Password@1
。 让我们将请求体中 URL 编码的数据发送给令牌端点,如下所示:
{
"grant_type": "password",
"username": "steve@jobs.com",
"Password": "Password@1"
}
让我们使用 Fiddler 将这个实例发送到Token
端点,如下所示:
图 13 -将具有授权类型的 User 实例发布到令牌端点
我们将在 Set-Cookie 报头中收到一个带有令牌的响应,如下图所示:
图 14 - Set-Cookie 报头中的 Token 响应
您也可以使用 AJAX post 请求或 c#发送此数据。 为了演示如何使用 c#获取令牌,我们在HomeController
中引入了一个名为GetToken
的操作和一个用于此操作的视图。 GetToken
的 c#代码如下:
public ActionResult GetToken()
{
var body = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>( "grant_type", "password" ),
new KeyValuePair<string, string>( "username", "test@test.com" ),
new KeyValuePair<string, string> ( "Password", "Sample@1" )
};
var content = new FormUrlEncodedContent(body);
using (var client = new HttpClient())
{
var response = client.PostAsync("http://localhost:61486/Token", content).Result;
var result = response.Content.ReadAsStringAsync().Result;
ViewBag.token = JsonConvert.DeserializeObject<Dictionary<string, string>>(result)["access_token"];
}
return View();
}
我们构造带有用户名和密码以及授权类型的请求体。 然后,我们将内容发布到 URLhttp://localhost:61486/Token/
。 最后,我们对响应内容进行反序列化,并将访问令牌分配给 ViewBag 命名的令牌。 在GetToken
视图中,我们打印分配给视图袋的访问令牌,如下图所示:
图 15 -视图上打印出检索到的访问令牌
发送经过验证的请求
在前面的部分中,我们实现了如何通过username
和password
从服务器检索访问令牌。 现在,在接收到的访问令牌的帮助下,让我们发送经过认证的请求。 经过认证的请求将在请求中有一个 Authorization 头。 我们通过 Fiddler 发送请求。 请求和响应如下截图所示:
图 16 -发送带有承载令牌的授权请求
我们也可以在 c#代码中使用HttpClient
在头文件中发送Bearer
令牌,如下所示:
using (var client = new HttpClient())
{
var token = "access_token";
client.DefaultRequestHeaders.Add("Authorization", String.Concat("Bearer ", token));
var response = client.GetAsync("http://localhost:61486/api/Values").Result;
var values = response.Content.ReadAsStringAsync().Result;
}
提示
注意:总是建议为 Web API 设置 SSL,以促进这种类型的认证机制。
总结
华友世纪! 我们刚刚使用基于令牌的认证来保护我们的 Web API。
在本章中,您学习了如何在 IIS 中托管 OWIN,以及如何将 Web API 添加到 OWIN 管道中。 您还学习并理解了本地登录认证的流程。
我们演练了如何发送未经授权的请求,并了解了其影响。
然后,我们发送用户名和密码以获得访问令牌,以便进一步访问需要经过认证的请求的资源。
最后,您看到了如何在请求的 Authorization 头中发送承载令牌并访问受保护的资源。
在下一章中,让我们通过使用认证过滤器启用基本认证来保护 Web API。
让我们把安全措施提高到更高一级!
版权属于:月萌API www.moonapi.com,转载请注明出处