当您选择个人账户在Web API项目模板,项目包含一个令牌授权服务器验证用户凭证和问题。下面的图显示了相同的凭证流的Web API组件。
发送一个未经授权的请求
首先,运行应用程序并单击按钮调用的API。当请求完成后,您应该看到一条错误消息在结果框。这是因为要求不包含一个访问令牌,所以请求授权。
调用API按钮发送一个AJAX请求~/api/values,调用一个Web API控制器动作。这是部分发送AJAX请求的JavaScript代码。在样例应用程序中,所有的JavaScript应用程序代码位于Scripts\app.js file文件。
// If we already have a bearer token, set the Authorization header.
var token = sessionStorage.getItem(tokenKey);
var headers = {};
if (token) {
headers.Authorization = 'Bearer ' + token;
}
$.ajax({
type: 'GET',
url: 'api/values/1',
headers: headers
}).done(function (data) {
self.result(data);
}).fail(showError);
直到用户登录,没有不记名的令牌,因此没有授权请求头。这使请求返回一个401错误。
Here is the HTTP request.
GET https://localhost:44305/api/values HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Accept-Language: en-US,en;q=0.5
X-Requested-With: XMLHttpRequest
Referer: https://localhost:44305/
HTTP response:
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
WWW-Authenticate: Bearer
Date: Tue, 30 Sep 2014 21:54:43 GMT
Content-Length: 61
{"Message":"Authorization has been denied for this request."}
注册用户
发送一个POST 请求到 ~/api/Account/Register/. body是已个json对象. Here is the JavaScript code that sends the request:
var data = {
Email: self.registerEmail(),
Password: self.registerPassword(),
ConfirmPassword: self.registerPassword2()
};
$.ajax({
type: 'POST',
url: '/api/Account/Register',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(data)
}).done(function (data) {
self.result("Done!");
}).fail(showError);
HTTP request:
POST https://localhost:44305/api/Account/Register HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: https://localhost:44305/
Content-Length: 84
{"Email":"alice@example.com","Password":"Password1!","ConfirmPassword":"Password1!"}
HTTP response:
HTTP/1.1 200 OK
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 00:57:58 GMT
Content-Length: 0
这个请求是由AccountController处理类。在内部,AccountController使用ASP.NET身份管理成员数据库。
如果你在本地运行应用程序从Visual Studio用户帐户存储在LocalDB,AspNetUsers表。查看表在Visual Studio中,单击视图菜单,选择Server Explorer,然后扩大数据连接。
得到一个访问Token
到目前为止,我们还没有做任何OAuth,但现在我们将看到OAuth授权服务器,当我们请求一个访问令牌。示例应用程序的登录区域,输入电子邮件和密码,点击登录。
The Log In button sends a request to the token endpoint. The body of the request contains the following form-url-encoded data:
- grant_type: "password"
- username: <the user's email>
- password: <password>
Here is the JavaScript code that sends the AJAX request:
var loginData = {
grant_type: 'password',
username: self.loginEmail(),
password: self.loginPassword()
};
$.ajax({
type: 'POST',
url: '/Token',
data: loginData
}).done(function (data) {
self.user(data.userName);
// Cache the access token in session storage.
sessionStorage.setItem(tokenKey, data.access_token);
}).fail(showError);
HTTP request:
POST https://localhost:44305/Token HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://localhost:44305/
Content-Length: 68
grant_type=password&username=alice%40example.com&password=Password1!
HTTP response:
HTTP/1.1 200 OK
Content-Length: 669
Content-Type: application/json;charset=UTF-8
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 01:22:36 GMT
{
"access_token":"imSXTs2OqSrGWzsFQhIXziFCO3rF...",
"token_type":"bearer",
"expires_in":1209599,
"userName":"alice@example.com",
".issued":"Wed, 01 Oct 2014 01:22:33 GMT",
".expires":"Wed, 15 Oct 2014 01:22:33 GMT"
}
发送一个身份验证请求
现在我们有一个不记名的令牌,我们可以做出一个身份验证请求API。这是通过设置授权请求头。单击按钮再次看到这个调用API。
HTTP request:
GET https://localhost:44305/api/values/1 HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Authorization: Bearer imSXTs2OqSrGWzsFQhIXziFCO3rF...
X-Requested-With: XMLHttpRequest
HTTP response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 01:41:29 GMT
Content-Length: 27
"Hello, alice@example.com."
Log Out
因为浏览器不缓存凭证或访问令牌,退出是一个简单的问题“忘记”的令牌,通过移除它从会话存储:
self.logout = function () {
sessionStorage.removeItem(tokenKey)
}
理解个人账户项目模板
When you select Individual Accounts in the ASP.NET Web Application project template, the project includes:
- An OAuth2 authorization server.
- A Web API endpoint for managing user accounts
- An EF model for storing user accounts.
Here are the main application classes that implement these features:
-
AccountControlle
r. Provides a Web API endpoint for managing user accounts. TheRegister
action is the only one that we used in this tutorial. Other methods on the class support password reset, social logins, and other functionality. -
ApplicationUser
, defined in /Models/IdentityModels.cs. This class is the EF model for user accounts in the membership database. -
ApplicationUserManager
, defined in /App_Start/IdentityConfig.cs This class derives from UserManager and performs operations on user accounts, such as creating a new user, verifying passwords, and so forth, and automatically persists changes to the database. -
ApplicationOAuthProvider
. This object plugs into the OWIN middleware, and processes events raised by the middleware. It derives from OAuthAuthorizationServerProvider.
Configuring the Authorization Server
In StartupAuth.cs, the following code configures the OAuth2 authorization server.
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// Note: Remove the following line before you deploy to production:
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
The TokenEndpointPath
property is the URL path to the authorization server endpoint. That's the URL that app uses to get the bearer tokens.
The Provider
property specifies a provider that plugs into the OWIN middleware, and processes events raised by the middleware.
Here is the basic flow when the app wants to get a token:
- To get an access token, the app sends a request to ~/Token.
- The OAuth middleware calls
GrantResourceOwnerCredentials
on the provider. - The provider calls the
ApplicationUserManager
to validate the credentials and create a claims identity. - If that succeeds, the provider creates an authentication ticket, which is used to generate the token.
The OAuth middleware doesn't know anything about the user accounts. The provider communicates between the middleware and ASP.NET Identity. For more information about implementing the authorization server