When you select a personal account in the Web API project template, the project contains a token authorization server to verify user credentials and issues. The following figure shows the Web API components for the same credential flow.
To send an unauthorized request
First, run the application and click the API called by the button. when the request is complete, you should see an error message in the Results box. This is because the requirement does not include an access token, so authorization is requested.
Call the API button to send an AJAX request ~/api/values, invoking a Web API controller action. This is part of the JavaScript code that sends AJAX requests. In the sample application, all the JavaScript application code is located in the Scripts\app.js file .
Javascript
//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);
There is no bearer token until the user logs in, so there is no authorization request header. This causes the request to return a 401 error.
This is the HTTP request.
Console
GET https://localhost:44305/api/values HTTP/1.1Host: localhost:44305User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0Accept: */*Accept-Language: en-US,en;q=0.5X-Requested-With: XMLHttpRequestReferer: https://localhost:44305/
HTTP Response:
Console
HTTP/1.1 401 UnauthorizedContent-Type: application/json; charset=utf-8Server: Microsoft-IIS/8.0WWW-Authenticate: BearerDate: Tue, 30 Sep 2014 21:54:43 GMTContent-Length: 61{"Message":"Authorization has been denied for this request."}
Registered users
Send a POST request to ~/api/account/register/. Body is a JSON object. Here's the JavaScript code that sends the request:
Copyjavascript
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:
Console
post https://localhost:44305/api/account/register HTTP/1.1< Span class= "Hljs-attribute" >host:localhost:44305user-agent:mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) gecko/20100101 firefox/32.0accept: */*content-type:application/json; Charset=utf-8x-requested-with:xmlhttprequestReferer: Https://localhost:44305/content-length:84 { "Email": "[email protected]", "Password": "password1!", "ConfirmPassword": "password1!"}
HTTP Response:
Console
200 OKServer: Microsoft-IIS/8.0Date: Wed, 01 Oct 2014 00:57:58 GMTContent-Length: 0
This request is handled by the AccountController class. internally, AccountController uses the ASP . NET Identity Management member database.
If you run the application locally from the Visual Studio user account stored in the Localdb,aspnetusers table. view table in Visual Studio, click the View menu, select Server Explorer, and then expand the data connection.
Get an access token
So far, we haven't done any oauth yet, but now we'll see the OAuth authorization server when we request an access token. Login area of the sample application, enter your email and password, and click Sign In.
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's the JavaScript code that sends the AJAX request:
Javascript
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:
Console
POST https://localhost:44305/Token HTTP/1.1Host: localhost:44305User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0Accept: */*Content-Type: application/x-www-form-urlencoded; charset=UTF-8X-Requested-With: XMLHttpRequestReferer: https://localhost:44305/Content-Length: 68grant_type=password&username=alice%40example.com&password=Password1!
HTTP Response:
Console
http/1.1$ OKcontent-length:669content-type:application/json;charset=utf-8server:microsoft-iis/8.0 date:wed, 01:22:36 GMT{ "Access_token":"Imsxts2oqsrgwzsfqhixzifco3rf ...", "Token_type ":" bearer ", " expires_in ":1209599, " userName ":" [email protected] ", ". Issued ":" Wed, 01:22:33 GMT ", ". Expires ":" Wed, Oct 01:22:33 GMT "}
Send an authentication request
Now that we have a bearer token, we can make an authentication request API. This is done by setting the authorization request header. Click the button again to see this call API.
HTTP Request:
Console
GET https://localhost:44305/api/values/1 HTTP/1.1Host: localhost:44305User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0Accept: */*Authorization: Bearer imSXTs2OqSrGWzsFQhIXziFCO3rF...X-Requested-With: XMLHttpRequest
HTTP Response:
Console
200 OKContent-Type: application/json; charset=utf-8Server: Microsoft-IIS/8.0Date: Wed, 01 Oct 2014 01:41:29 GMTContent-Length: 27"Hello, [email protected]example.com."
Log out
Because the browser does not cache credentials or access tokens, exiting is a simple matter of "forgetting" the token by removing it from the session store:
Javascript
function () { sessionStorage.removeItem(tokenKey)}
Understanding Individual Account Project templates
When you select individual Accounts in the ASP. 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 is the main application classes that implement these features:
AccountControlle
R. Provides a WEB API endpoint for managing user accounts. The action is the only one, and Register
we used in this tutorial. Other methods to the class support password reset, social logins, and other functionality.
ApplicationUser
, defined In/models/identitymodels.cs. This was 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, Su Ch as creating a new user, verifying passwords, and so forth, and automatically persists changes to the database.
ApplicationOAuthProvider
. This object plugs to 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.
copyc#
publicclientid = "self"; oauthoptions = new oauthauthorizationserveroptions{tokenendpointpath = new PathString ( Span class= "hljs-string" > "/token"), Provider = new Applicationoauthprovider ( Publicclientid), Authorizeendpointpath = new pathstring ( "/api /account/externallogin "), Accesstokenexpiretimespan = Timespan.fromdays (14), //note:remove the following line before your deploy to Production:allowinsecurehttp = true}; //Enable the application to use bearer tokens to authenticate Usersapp. Useoauthbearertokens (oauthoptions);
The property is the URL of path to the TokenEndpointPath
authorization server endpoint. That's the URL that app uses to get the bearer tokens.
Provider
The property specifies a provider this plugs into the OWIN middleware, and processes events raised by the middleware .
Here's 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 on the
GrantResourceOwnerCredentials
provider.
- The provider calls the to
ApplicationUserManager
validate the credentials and create a claims identity.
- If that succeeds, the provider creates a 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. For more information about implementing the authorization server
Web API2 using default identity