Talk about the third-party authentication based on OAuth 2.0 [medium]

Source: Internet
Author: User
Tags oauth

Although we discussed the 4 predefined authorization grant types and their respective scenarios for obtaining access tokens in the previous article, I think many readers who have not been in touch with OAuth 2.0 will still have a sense of "not worth the cloud", So in the introduction, we will use examples to demonstrate the way to implicit and authorization code these two commonly used authorization grant for in-depth introduction. This chapter focuses on implicit Authorization Grant.

Implicit Authorization Grant Authorization process

Suppose our client application integrates the Windows Live Connect API Authentication Service, and calls the appropriate Web API to get the personal information of the currently logged-on user after successfully obtaining authorization from the user and obtaining access token. In general, implicit types of authorization grant are mostly used by client applications that use browsers as execution contexts, in other words, such clients are JavaScript programs that execute in a browser. Represents the complete process of authorizing, obtaining access token, and ultimately obtaining a protected resource (the user's personal information) from a client application that uses the implicit type of authorization grant.

As shown in the image on the right, the user is redirected to the authorization server (login.live.com) by the client app, with the address "https://login.live.com/oauth20_authorize.srf". The relevant input parameters are in the form of a query string, and the parameters that must be supplied are contained in the following list.

    • Response_type: Represents the type of object that the request wants to get, where we want to get access token, so the value specified here is "Token".
    • Redirect_uri: Represents the address that the authorization server redirects after obtaining a user's authorization and completing authentication to the user, and Access token is appended to the URL as a hash (#). The client app uses this address to receive access tokens.
    • CLIENT_ID: A clientid that uniquely identifies an authorized client app.
    • Scope: Represents the extent of authorization, and if "wl.signin" means allowing a user to log on directly to live Services from the client app, if scope is "Wl.basic" then the client app gets contact information. If a reader friend wants to know about Windows Live Connect specifically supports those scopes, you can check the official documentation for the Windows Live Connect API.

If the current user is not logged on to Windows Live Services, the login window will appear, and when the user enters the correct Windows Live account and password and successfully authenticates, the browser appears on the authorization page as shown, The set of permissions that you need to grant depends on the scope parameter described above. We click the "Yes" button to complete the authorization, after successful authorization, this authorization page will not appear in subsequent requests.

After the authorization server obtains the user's authorization, an access Token is generated. Next, it extracts the redirect address specified in the request (that is, the Redirect_uri parameter), appends the generated access token to the address as a hash (#), and eventually returns a redirected response for the new address that carries the access token. As shown in the first figure, the redirect address we are using is "Http://www.myapp.com/capturetoken", then the final browser will redirect to the address "http://www.myapp.com/capturetoken#acess _token={accesstoken} "on.

This redirect address corresponds to the page where the client app needs to get an authorization resource, which can get access Token directly from the URL that represents the current address and use it to get the target resource. For our example, it needs to get the basic information of the current Windows Live account, the requested address is "https://apis.live.net/v5.0/me", and Access token is in the form of a query string ("? access_token= {Accesstoken} ") is provided to the resource server, which verifies the legality of the request and returns the current user's basic information as JSON to the client application, in the case of a successful validation.

Example Demo: Creating a Web API app with implicit Authorization Grant

Next we create an ASP. NET Web API program to implement the above application scenario. We first need to register a clientid for the application as described in the previous article, and if we have created an app on Windows Live Connect, we can use the app's ClientID directly.

Suppose we created an app with "https://www.artech.com" as the domain name in Windows Live Connect, we need to take advantage of the Hosts file ("%windir%\system32\drivers\etc\ Hosts ") maps this domain name to the native IP address (127.0.0.1), as shown in the following mapping script. In addition, because we are using HTTPS and hosting with local IIS, we need to add an HTTPS binding for the site where the Web API app resides.

   1:127.0.0.1 www.artech.com

Before we introduce the principles of certification implementation, let's start by demonstrating the results that are ultimately achieved. In the ASP. NET Web API application, we define the following Democontroller, which inherits from Apicontroller, which has the only action method getprofile that is used to get the personal basic information of the currently logged-on user. In this method, it extracts access tokens from the current request through our defined extension method Trygetaccesstoken, and then uses it to invoke the Web API provided by Windows Live Connect (https:// apis.live.net/v5.0/me).

   1: [Authenticate ("Https://www.artech.com/webapi/account/capturetoken" )
   2:public class Democontroller:apicontroller
   3: {
   4: Public     httpresponsemessage GetProfile ()
   5:     {
   6:         string Accesstoken;
   7:         if (this. Request.trygetaccesstoken (out Accesstoken))
   8:         {
   9:             using (HttpClient client = new HttpClient ())
  Ten:             {
  One:                 string address = string. Format ("https://apis.live.net/v5.0/me?access_token={0}", Accesstoken);
  :                 return client. Getasync (address). Result;
  :             }
  :         }
  :         return new Httpresponsemessage (httpstatuscode.badrequest) {reasonphrase = "No access token"};
  :     }
  17:}

The implementation of Integrated Windows Live Connect authentication is ultimately done by applying the Authenticateattribute feature on the Democontroller type, which is a authenticationfilter, The URL as a parameter points to a Web page that gets and forwards access tokens. Now we use the browser directly to invoke the action method GetProfile defined in Democontroller, and if the current user is not logged in to Windows Live, the browser will automatically redirect to the Windows Live login screen. When we enter the correct Windows Live account and password, the current user's basic information is displayed in JSON format on the browser (if the app has not been authorized, as shown in the page will be rendered), the effect as shown.

The Authenticateattribute feature applied on the Democontroller completes the redirection of the authorization page and the request and reception of Access tokens. In addition, in order for the browser to be able to automatically send access tokens after the first authentication, we used Authenticateattribute to write access tokens to the cookie, which is similar to the forms authentication. However, in terms of security, using cookies to carry security tokens can cause a security issue called cross-site request forgery (Csrf:cross-site requests forgery), so it is safer to use HTTP headers as a carrier for security tokens.

The code snippet shown below embodies the definition of the entire Authenticateattribute feature, and we can see that it implements both Iauthenticationfilter and Iactionfilter. The string constant CookieName represents the cookie name that carries access token, and the read-only attribute Capturetokenuri indicates that the authorization server sent the redirect address used by access token, which points to a Web page we designed by us. The page automatically sends a request to the address where the target resource is located after receiving the access token, which carries the access token in the form of a query string. (The reason we need to use a Web page to receive and re-send access tokens in the client (browser) is because the authorization server will return the access token as the hash (#) portion of the redirect Uri, so it is not available on the service side and can only be collected at the client.) The purpose of this web page is to obtain the access token on the client and send it to the server. )

   1: [AttributeUsage (attributetargets.class| AttributeTargets.Method)]
   2:public class Authenticateattribute:filterattribute, Iauthenticationfilter, Iactionfilter
   3: {
   4: Public     const string cookiename = "Accesstoken";
   5: Public     string     Capturetokenuri {get; private set;}
   
   7: Public     Authenticateattribute (string Capturetokenuri)
   8:     {
   9: This         . Capturetokenuri = Capturetokenuri;
  Ten:     }
  
  : Public     Task Authenticateasync (httpauthenticationcontext context, CancellationToken CancellationToken)
  :     {
  :         return task.fromresult<object> (NULL);
  :     }
  
  : Public     Task Challengeasync (httpauthenticationchallengecontext context, CancellationToken CancellationToken)
  :     {
  :         string Accesstoken;
  :         if (!context. Request.trygetaccesstoken (out Accesstoken))
  :         {
  :             String clientId = "000000004810c359";
  :             String Redirecturi = string. Format ("{0}?requesturi={1}", this. Capturetokenuri, context. Request.requesturi);
  :             String scope = "Wl.signin%20wl.basic";
  
  :             string uri = "HTTPS://LOGIN.LIVE.COM/OAUTH20_AUTHORIZE.SRF";
  :             uri + = "? Response_type=token";
  :             uri + = "&redirect_uri={0}&client_id={1}&scope={2}";
  :             uri = String.Format (URI, Redirecturi, clientId, scope);
  :             context. Result = new Redirectresult (new URI), context. Request);
  :         }
  :         return task.fromresult<object> (NULL);
  :     }
  
  : Public     task
  :     {
  Panax Notoginseng:         httpresponsemessage response = continuation (). Result;
  A:         string accesstoken;
  :         if (ActionContext.Request.TryGetAccessToken (out Accesstoken))
  Max:         {
  A:             response. Setaccesstoken (Actioncontext.request, Accesstoken);
  :         }
  :         return task.fromresult
  :     }
  45:}

In the implementation of the Challengeasync method, which sends a "challenge" response to the client during the authentication process, we use the custom extension method Trygetaccesstoken to try to get the carrying access Token from the current request. If such access token does not exist, we implement a Redirectresult object for Windows Live by setting a httpauthenticationchallengecontext for the result property of the The redirection of the Connect authorization page, related parameters (Respone-type, Redirect_uri, client_id, and scope) are provided in the form of a query string.

It is worth mentioning that as the redirect address of the parameter Redirect_uri, we will be the address of the current request as the query string (named "RequestUri") appended to the Capturetokenuri on the resulting URI as the value of the parameter, Address of the current request the official web page sends the destination address of access token.

Another implementation of the Executeactionfilterasync method complex is to write access tokens into the response cookie, and the specific operation is implemented in our custom extension method Setaccesstoken. The following code fragment gives the definition of two extension methods Setaccesstoken and Trygetaccesstoken.

   1:public Static Class Extensions
   2: {
   3:     public  static bool Trygetaccesstoken (this httprequestmessage request, out string accesstoken)
   4:     {
   5:         //Get access Token from a cookie
   6:         accesstoken = null;
   7:         Cookieheadervalue cookievalue = Request. Headers.getcookies (Authenticateattribute.cookiename). FirstOrDefault ();
   8:         if (null! = Cookievalue)
   9:         {
  Ten:             Accesstoken = CookieValue.Cookies.FirstOrDefault (). Value;
  One:             return true;
  :         }
  13:         
           //Get access Token from the query string
  :         Accesstoken = httputility.parsequerystring (Request. Requesturi.query) ["Access_token"];
  :         return!string. IsNullOrEmpty (Accesstoken);
  :     }
  
  : public     static void Setaccesstoken (this httpresponsemessage response, httprequestmessage request, string Accesstoken)
  :     {
  :         if (request. Headers.getcookies (Authenticateattribute.cookiename). Any ())
  :         {
  :             return;
  :         }
  :         Cookieheadervalue cookie = new Cookieheadervalue (Authenticateattribute.cookiename, Accesstoken)
  :         {
  :             HttpOnly = True,
  :             Path = "/"
  :         };
  A:         response. Headers.addcookies (new cookieheadervalue[] {cookie});
  :     }
  32:}

In the example we demonstrate, the Capturetokenuri property of the Authenticateattribute attribute applied on the Democontroller type ("https://www.artech.com/webapi/ Account/capturetoken ") points to a controller that is defined in AccountController such a controller (ASP. NET MVC, not ASP. NET Web The Httpcontroller of the API) Capturetoken the action method, which is defined as shown below.

   1:public class Accountcontroller:controller
   2: {
   3: Public     actionresult Capturetoken (String requesturi)
   4:     {
   5:         Viewbag.requesturi = RequestUri;
   6:         return View ();
   7:     }
   8:}

Because Authenticateattribute in the API that calls Windows Live Connect, the redirect address specified by access token has a query string named "RequestUri" whose value is exactly the call to the Web The address of the API, which is automatically bound to the RequestUri parameter of the action method Capturetoken. If the code snippet above shows, the method passes the address in the form of viewbag to the rendered view.

   1: 
   2:     
   3:         <script src= "@Url. Content (" ~/scripts/jquery-1.10.2.js ")" ></script>
   4:         <script type= "Text/javascript" >
   5:             $ (document). Ready (function () {
   6:                 var redirecturi = ' @ViewBag. RequestUri ';
   7:                 if (Redirecturl.indexof ('? ') >= 0) {
   8:                     RedirectURL + = "&" + location.hash.slice (1)
   9:                 }
  Ten:                 else {
  One:                     RedirectURL + = "?" + location.hash.slice (1)
  :                 }
  :                 location.href = Redirecturi;
  :             });
  :         </script>
  :     
  : 

The code snippet above represents the definition of the action method Capturetoken corresponding to the view. In this view, we get access Token from the hash (#) portion of the current address and append it as a query string to the resource access address obtained from ViewBag, and carry access by setting the href attribute of the location Token initiates a call to the Web API again.

Talk about the third-party authentication based on OAuth 2.0 [medium]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.