Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store access token? (Oauth 2, Auth code flow)

From what i understand the purpose of the Authorization Code flow is to exchange the auth code for access token. This exchange happens between the server which serves the page and authorization server so that the actual access token is not exposed to the client user.

How should the page server store the access token once it is obtained? I was learning from a Pluralsight example in which there is this part of code:

    public static HttpClient GetClient()     {         HttpClient client = new HttpClient();         var accessToken = RequestAccessTokenAuthorizationCode();         client.SetBearerToken(accessToken);          client.BaseAddress = new Uri(IdentityConstants.API);         client.DefaultRequestHeaders.Accept.Clear();         client.DefaultRequestHeaders.Accept.Add(             new MediaTypeWithQualityHeaderValue("application/json"));          return client;     }      private static string RequestAccessTokenAuthorizationCode()     {         // did we store the token before?         var cookie = HttpContext.Current.Request.Cookies.Get("ClientMVCCookie.AuthCode");         if (cookie != null && cookie["access_token"] != null && !string.IsNullOrEmpty(cookie["access_token"]))         {             return cookie["access_token"];         }          // no token found - request one          // we'll pass through the URI we want to return to as state         var state = HttpContext.Current.Request.Url.OriginalString;          var authorizeRequest = new IdentityModel.Client.AuthorizeRequest(             IdentityConstants.AuthEndoint);          var url = authorizeRequest.CreateAuthorizeUrl(IdentityConstants.MVCClientSecret, "code", "management secret",             IdentityConstants.MVCAuthCodeCallback, state);          HttpContext.Current.Response.Redirect(url);          return null;     } } 

This will cause each request to check if there is an access token stored in the cookie. If not then the flow will be initiated. The callback looks like this:

public class CallbackController : Controller {     // GET: STSCallback     public async Task<ActionResult> Index()     {         // get the authorization code from the query string         var authCode = Request.QueryString["code"];          // with the auth code, we can request an access token.         var client = new TokenClient(             IdentityConstants.TokenEndoint,             "mvc_client_auth_code",              IdentityConstants.MVCClientSecretAuthCode);          var tokenResponse = await client.RequestAuthorizationCodeAsync(             authCode,             IdentityConstants.MVCAuthCodeCallback);          // we save the token in a cookie for use later on         var cookie = Response.Cookies["ClientMVCCookie.AuthCode"];         cookie.Expires = DateTime.Now.AddMinutes(1);         cookie["access_token"] = tokenResponse.AccessToken;          // get the state (uri to return to)         var state = Request.QueryString["state"];          // redirect to the URI saved in state         return Redirect(state);     } } 

Doesn't storing the access token in the cookie defeath the whole purpose of the authorization code flow? The cookie will be transmitted to the client browser thus exposing it to the client? Am i missing something? It this is not the correct way to store the token, how should it be stored?

like image 947
BodzioSamolot Avatar asked Jun 02 '17 08:06

BodzioSamolot


People also ask

How do I store access tokens?

Most guidelines, while advising against storing access tokens in the session or local storage, recommend the use of session cookies. However, we can use session cookies only with the domain that sets the cookie. Another popular suggestion is to store access tokens in the browser's memory.

How can I get access token using authorization code?

To get a new access token, use the refresh token as you would an authorization code, but with a grant_type value of refresh_token and a refresh_token parameter that holds the contents of the refresh token. The type of grant being used. To exchange a refresh token for an access token, use refresh_token .

What is authorization code flow in oauth2?

The OAuth 2.0 authorization code grant type, or auth code flow, enables a client application to obtain authorized access to protected resources like web APIs. The auth code flow requires a user-agent that supports redirection from the authorization server (the Microsoft identity platform) back to your application.


Video Answer


1 Answers

The client, in OAuth terminology, is the component that makes requests to the resource server, in your case, the client is the server of a web application (NOT the browser).

Therefore, the access token should be stored on the web application server only. It should not be exposed to the browser, and it doesn't need to, because the browser never makes any direct requests to the resource server. It talks to the web application server instead, which in turn makes requests to the resource server using the access token.

How the browser authenticates itself with the web application server has nothing to do with OAuth 2.0. For example, it might be a regular session cookie, and the web application server might associate each session or each user with an access token.

The token request, which exchanges the authentication code for an access token, is done by the web application server, and the web application server should authenticate itself with the authorization server (e.g., using a shared client_secret).

Authorization code flow ensures that the client can be authenticated, which protects against malicious clients posing as legitimate clients. Not all web application clients have a server component, and in some cases, requests to the resource server are made directly by JavaScript code in the browser. In such situations, the browser is the client, and the access token must be stored by the browser (in a JavaScript variable, local storage or a cookie). In this case, the client cannot be authenticated (but a reasonable amount of security may be achieved by using TLS and the server redirecting only to registered endpoint URLs).

Recommended reading regarding OAuth 2.0 security: https://www.rfc-editor.org/rfc/rfc6819#section-4.3.3 (RFC 6819)

like image 141
Florian Winter Avatar answered Sep 17 '22 18:09

Florian Winter