In the previous blog post, we successfully invoked the user-independent Web API by using Access tokens that were received by OAuth's client Credential Grant authorization method (which only validates the calling client, without verifying the logged-in user).
In this blog post, we will get access Token in the authorization mode (Grant_type=password) of OAuth's Resource Owner Password Credentials Grant and call the user with this token The associated Web API.
The corresponding scenario is to develop a mobile app for your own website (not a third-party app) that requires users to log on to the app without having to authorize the data that the app can access.
According to the OAuth specification, the client gets access Token in the following way:
Post/token http/1.1host:server.example.comauthorization:basic Czzcagrsa3f0mzpnwdfmqmf0m2jwcontent-type: application/x-www-form-urlencodedgrant_type=password&username=johndoe&password=a3ddj3w
Based on the above request method, a simple client is implemented in C # with HttpClient, with the following code:
public class oauthclienttest{private HttpClient _httpclient; Public Oauthclienttest () {_httpclient = new httpClient (); _httpclient.baseaddress = new Uri ("http://openapi.cnblogs.com"); } [Fact] public async Task get_accesss_token_by_resource_owner_password_credentials_grant () {Console.wri Teline (await Getaccesstoken ()); } Private Async Task<string> Getaccesstoken () {var clientId = "1234"; var Clientsecret = "5678"; var parameters = new dictionary<string, string> (); Parameters. ADD ("Grant_type", "password"); Parameters. ADD ("username", "blog Park Team"); Parameters. ADD ("Password", "cnblogs.com"); _httpclient.defaultrequestheaders.authorization = new Authenticationheadervalue ("Basic", convert.to Base64string (Encoding.ASCII.GetBytes (clientId + ":" + Clientsecret)); var response = await _httpclient.postasync ("/token", New FormurlencodEdcontent (parameters)); var responsevalue = await response. Content.readasstringasync (); if (response. StatusCode = = System.Net.HttpStatusCode.OK) {return jobject.parse (responsevalue) ["Access_token"]. Value<string> (); } else {Console.WriteLine (responsevalue); return string. Empty; } }}
(Note: The Client_id/client_secret here is changed to Basic Authorization to better follow the OAuth specification than before)
On the server side, based on Owin OAuth, the authorization method for Resource Owner Password Credentials Grant is simply overloaded Oauthauthorizationserverprovider.grantresourceownercredentials () method. The code is as follows:
public class cnblogsauthorizationserverprovider:oauthauthorizationserverprovider{ //... public override Async Task Grantresourceownercredentials ( oauthgrantresourceownercredentialscontext context) { //Call the backend login service to verify the username and password var oauthidentity = new Claimsidentity (context. Options.authenticationtype); Oauthidentity.addclaim (New Claim (claimtypes.name, context. UserName)); var ticket = new Authenticationticket (oauthidentity, New Authenticationproperties ()); Context. Validated (ticket); Await base. Grantresourceownercredentials (context);} }
The complete Cnblogsauthorizationserverprovider implementation code is as follows (compared to the previous context. Trygetformcredentials was changed to context. Trygetbasiccredentials):
Cnblogsauthorizationserverprovider
This way, you can get Access tokens by running the client program.
Next, we take access tokens that we get in this way, and we can invoke the Web APIs that are relevant to the user.
On the server side we test with a simple Web API, the code is as follows:
public class userscontroller:apicontroller{ [authorize] public string GetCurrent () { return User.Identity.Name; You can call the background User Service, get the user-related number, or verify the user's permissions to do the appropriate action }}
The client then calls this web API with Access tokens that are Grant_type=password, and the client adds the following code:
[Fact]public async Task call_webapi_by_resource_owner_password_credentials_grant () { var token = await Getaccesstoken (); _httpclient.defaultrequestheaders.authorization = new Authenticationheadervalue ("Bearer", token); Console.WriteLine (Await _httpclient.getasync ("/api/users/current")). Content.readasstringasync ());}
The client runs the following results:
"Blog Park Team"
Call succeeded! The result of the run is the username used to get access tokens.
Combined with the existing security mechanisms of ASP., with the power of OWIN, Microsoft.Owin.Security.OAuth does make it easier to develop OAuth-based Web APIs.
Tags: OAuth, WebAPI classification:. Net Framework, ASP.
Unity + iBatis + ASP network MVC System Setup