Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The Authorization Code Grant is used to request an authorization code that can be exchanged for an ID token and, typically, an access token. This grant is advantageous in that because tokens cannot be intercepted, as they are never exposed to the user agent (typically, a web browser). The flow is redirection-based, so the client needs to be able to interact with the resource owner’s user agent to initiate and complete the process. 

The sequence for this flow is as follows:

Image Removed

  • The client application initiates the flow by directing the resource owner’s user agent to the EmpowerID Authorization endpoint with the required parameters. These parameters include a response type, client identifier, scope, and a redirect URL that specifies where to send the user agent after the resource owner authenticates.

  • The resource owner submits credentials.

  • Upon successful authentication, the Authorization server sends an authorization code and identity token to the specified redirect URL.

  • The client application calls the EmpowerID Token endpoint to exchange the authorization code for an access token and a refresh token.

  • The Authorization server authenticates the client application by verifying the Client ID and Client Secret, validates the authorization code, checks the redirect URL and issues the access and refresh tokens.  

    Authorization Code Grant Flow

    The diagram below provides an overview of the OAuth 2.0 Authorization Code Grant flow as implemented in EmpowerID. Each numbered step in the diagram corresponds to a key part of the process, which we explain in detail in the following section. This flow is essential for understanding how the client application interacts with the Authorization and Token Endpoints to authenticate users and obtain tokens securely.

    Image Added

    Detailed Steps of the Authorization Code Grant Flow

    Now, let’s go through each step depicted in the diagram to understand how the OAuth 2.0 Authorization Code Grant flow works in detail:

    1. Initiate Authorization Request: The client application initiates the flow by directing the resource owner’s user agent to the EmpowerID Authorization endpoint (https://<EID Server>/oauth/v2/ui/authorize) with the required parameters:

      • response_type: Specifies the desired type of response, which must be code to initiate the authorization code flow.

      • client_id: The identifier for the client application requesting access.

      • scope: A space-separated list of access permissions being requested (e.g., openid for OpenID Connect).

      • redirect_uri: Specifies where the user agent should be redirected after successful authentication.

      • Optional parameters, such as state (to prevent CSRF attacks) and nonce (to mitigate replay attacks), can also be included for enhanced security.

    2. User Submits Credentials: The resource owner submits their credentials using a login form presented by the Authorization server. This may involve a traditional username-password combination, an external identity provider, or multi-factor authentication (MFA), depending on the security configuration.

    3. Authorization Code Issued: Upon successful authentication, the Authorization server redirects the user agent to the specified redirect_uri, including an authorization code and, if applicable, an identity token (id_token) in the query parameters. This redirect keeps tokens hidden from the user agent and ensures a secure transmission back to the client application.

    4. Token Request to Token Endpoint: The client application makes a back-channel request to the EmpowerID Token endpoint (https://<EID Server>/oauth/v2/token) to exchange the received authorization code for an access token and a refresh token. The request must include the following:

      • grant_type: Must be set to authorization_code.

      • client_id: The client application identifier.

      • client_secret: A secret key associated with the client application.

      • code: The authorization code obtained from Step 3.

      This request happens server-to-server, ensuring that sensitive information, such as the client_secret, remains secure.

    5. Tokens Issued to Client Application: The Authorization server verifies the client credentials, validates the authorization code, and ensures the redirect_uri matches the one used in Step 1. If all checks pass, the Authorization server issues an access token (for accessing protected resources) and a refresh token (for obtaining a new access token without requiring further user authentication).

    Tip

    You can download sample .NET framework code at https://dlempowerid.blob.core.windows.net/files/OAuthTestSampleCode.zip?sp=r&st=2024-02-02T14:42:35Z&se=2027-03-30T22:42:35Z&spr=https&sv=2022-11-02&sr=b&sig=l8mGw3b6%2Br5aQNtEh966Ya2U7G7067Q7NKw2tgEfspk%3D

    Authorization Code Grant

    1. Initiate a login request to the EmpowerID Authorization endpoint, https://<EID Server>/oauth/v2/ui/authorize

    Code Block
    https://<EID Server>/oauth/v2/ui/authorize
    ?client_id=xxxxxxxxxxxxxxxxxx
     &redirect_uri=https%3A%2F%2Ftestoauthapp.com%2FcallbackUrl
     &response_type=code
     &scope=openid
     &state=xxxxxxxxxxxxxxxxxx
     &nonce=xxxxxxxxxxxxxxxxxx

    Request Parameter

    Required/Optional

    Description

    response_type

    required

    Must be code to initiate authorization code flow. For OpenID Connect flowuse code id_token as response type.

    client_id 

    required

    Must be the EmpowerID OAuth application client identifier.

    redirect_uri 

    required

    The client app URL to which the authorization server will redirect after request approval. This URL should be registered in the Callback URLs on the EmpowerID OAuth application.

    scope

    required

    A space-separated list of strings that the user consents to. Values include openid for OpenID Connect flow.

    state 

    optional

    A random string value sent by the client to maintain session and prevent CSR attacks

    nonce

    optional

    A random string value sent by client to uniquely identify each request

    2. Authenticate using username and password or any of the allowed external identity providers.

    3. The Authorization server redirects to the redirect_uri with the response parameters in the query string.

    Code Block
    https://testoauthapp.com/callbackUrl
    ?state=xxxxxxxxxxxxxxxxxx
     &code= xxxxxxxxxxxxxxxxxx
     &id_token= xxxxxxxxxxxxxxxxxx

    Response Parameter

    Description

    state

    The value sent by the client to maintain the session

    code

    The authorization code generated by the authorization server

    id_token

    The identity token issued by the authorization server for OpenID Connect flow

    4. Exchange the code for an access token by calling the EmpowerID Token endpoint, https://<EID Server>/oauth/v2/token

    Code Block
    https://<EID Server>/oauth/v2/token
    ?client_id={The Client ID of the OAuth app you registered in EmpowerID}
     &client_secret={The Client Secret of the OAuth app you registered in EmpowerID}
     &grant_type=authorization_code
     &code=xxxxxxxxxxxxxxxxxx

    Request Parameter

    Required/Optional

    Description

    grant_type

    required

    Must be authorization_code to initiate authorization code flow.

    client_id 

    required

    Must be the EmpowerID OAuth application client identifier.

    client_secret  

    required

    Must be the EmpowerID OAuth application client secret.

    code 

    required

    The authorization code received from the authorization server

    5. Returns access token and refresh token in the response.

    Code Block
    {
        "access_token": "xxxxxxxxxxxxxxxxxxxxxx",
        "token_type": "Bearer",
        "expires_in": 3600,
        "refresh_token": "xxxxxxxxxxxxxxxxxxxxxx",
        "id_token": "xxxxxxxxxxxxxxxxxxxxxx",
        "id": "xxxxxxxxxxxxxxxxxxxxxx"
    }

    Authorization Code Grant using .NET Client Library

    1. Initialize ClientSettings by passing the client_id, client_secret, redirect_uri, token_endpoint, authorization_endpoint, tokeninfo_endpoint and userinfo_endpoint. Also, initialize a new AuthorizationCodeGrant by passing the clientSettings model.

    Code Block
    var clientSettings = new ClientSettings(
        “client_id”,
        “client_secret”,
        “redirect_uri”,
        “https://<EID Server>/oauth/v2/token”,
        “https://<EID Server>/oauth/v2/ui/authorize”,
        “https://<EID Server>/oauth/v2/tokeninfo”,
        “https://<EID Server>/oauth/v2/userinfo”);
                 
     var handler = new AuthorizationCodeGrant(clientSettings);

    2. Call the BuildAuthorizationRequestPacket() method to build authorization code flow parameters.

    Code Block
    //Generate random nonce and state
    var nonce = Guid.NewGuid().ToString("N");
    var state = Guid.NewGuid().ToString("N");
     
    //Use the below code for "code" flow to build parameters
    var parameters = handler.BuildAuthorizationRequestPacket
    (ParameterFormat.FormUrlEncoded, state, null, nonce, null);
            
    //Use the below code for "code id_token" flow to build parameters
    var responseTypes = new List<ResponseType> { ResponseType.id_token };
    var parameters = handler.BuildAuthorizationRequestPacket     
    (ParameterFormat.FormUrlEncoded, state, "openid", nonce, responseTypes);
     
    //Generate redirect URL
    var redirectUrl = string.Format("{0}?{1}", clientSettings.AuthorizeUrl, parameters);

    3. In the application’s callback method AuthorizationCodeGrantResponse() for example, extract the code and state, build an AuthorizationResponseModel model, and send it to the GetAccessToken() method.

    Code Block
    public ActionResult AuthorizationCodeGrantResponse(AuthorizationResponseModel model)
    {
      AuthorizationResponseModel authorizationResponseModel = new AuthorizationResponseModel() {Code = "xxxxxxx", State = state};
      AccessTokenResponseModel tokenResponseModel = null;
      try
      {
          tokenResponseModel = handler.GetAccessToken<AccessTokenResponseModel>(
              RequestMethod.POST,
              ParameterFormat.FormUrlEncoded,
              authorizationResponseModel,
              false);
      }
      catch {  //Handle error   }
    }

    Authorization Code Grant with PKCE (Proof Key for Code Exchange) Extension

    1. Initiate a login request to the EmpowerID Authorization endpoint, https://<EID Server>/oauth/v2/ui/authorize

    Code Block
    https://<EID Server>/oauth/v2/ui/authorize
    ?client_id=xxxxxxxxxxxxxxxxxx
     &redirect_uri=https%3A%2F%2Ftestoauthapp.com%2FcallbackUrl
     &response_type=code
     &state=xxxxxxxxxxxxxxxxxx
     &nonce=xxxxxxxxxxxxxxxxxx
     &scope=openid
     &code_challenge=xxxxxxxxxxxxxxxxxx
     &code_challenge_method=S256

    Request Parameter

    Required/Optional

    Description

    response_type

    required

    Must be code to initiate authorization code flow. For OpenID Connect flowuse code id_token as a response type.

    client_id 

    required

    Must be the EmpowerID OAuth application client identifier.

    redirect_uri 

    required

    The client app URL to which the authorization server will redirect after request approval. This URL should be registered in the Callback URLs on the EmpowerID OAuth application.

    scope

    required

    A space-separated list of strings that the user consents to. Values include openid for OpenID Connect flow.

    code_challenge_method

    recommended

    Specifies the transformation method used for the code_challenge. Permitted values are

    • plain

    • S256

    Defaults to plain if not present in the request

    code_challenge

    required

    The string derived from the code_verifier.

    • plain - code_challenge = code_verifier

    • S256 - code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

    Please refer to the PKCE RFC for generating the Code Verifier.

    state 

    optional

    A random string value sent by the client to maintain session and prevent CSR attacks

    nonce

    optional

    A random string value sent by client to uniquely identify each request

    2. Authenticate using username and password or any of the allowed external identity providers.

    3. Authorization server redirects to the redirect_uri with the response parameters in the query string.

    Code Block
    https://testoauthapp.com/callbackUrl
    ?state=xxxxxxxxxxxxxxxxxx
     &code= xxxxxxxxxxxxxxxxxx
     &id_token= xxxxxxxxxxxxxxxxxx

    Response Parameter

    Description

    state

    The value sent by the client to maintain the session

    code

    The authorization code generated by the authorization server

    id_token

    The identity token issued by the authorization server for OpenID Connect flow

    4. Exchange the code for an access token by calling the EmpowerID Token endpoint, https://<EID Server>/oauth/v2/token

    Code Block
    https://<EID Server>/oauth/v2/token
    ?client_id={The Client ID of the OAuth app you registered in EmpowerID}
     &client_secret={The Client Secret of the OAuth app you registered in EmpowerID}
     &grant_type=authorization_code
     &code=xxxxxxxxxxxxxxxxxx
     &code_verifier=xxxxxxxxxxxxxxxxxx

    Request Parameter

    Required/Optional

    Description

    grant_type

    required

    Must be authorization_code to initiate authorization code flow.

    client_id 

    required

    Must be the EmpowerID OAuth application client identifier.

    client_secret  

    required

    Must be the EmpowerID OAuth application client secret.

    code 

    required

    The authorization code received from the authorization server

    code_verifier

    required

    The Code Verifier valuegenerated by the client during the initial authorization request

    5. Returns access token and refresh token in the response.

    Code Block
    {
        "access_token": "xxxxxxxxxxxxxxxxxxxxxx",
        "token_type": "Bearer",
        "expires_in": 3600,
        "refresh_token": "xxxxxxxxxxxxxxxxxxxxxx",
        "id_token": "xxxxxxxxxxxxxxxxxxxxxx",
        "id": "xxxxxxxxxxxxxxxxxxxxxx"
    }

    Authorization Code Grant with PKCE Extension using .NET Client Library

    1. Initialize ClientSettings by passing the client_id, client_secret, redirect_uri, token_endpoint, authorization_endpoint, tokeninfo_endpoint and userinfo_endpoint. Also, initialize a new AuthorizationCodeGrant by passing the clientSettings model.

    Code Block
    var clientSettings = new ClientSettings(
        “client_id”,
        “client_secret”,
        “redirect_uri”,
        “https://<EID Server>/oauth/v2/token”,
        “https://<EID Server>/oauth/v2/ui/authorize”,
        “https://<EID Server>/oauth/v2/tokeninfo”,
        “https://<EID Server>/oauth/v2/userinfo”);
                 
     var handler = new AuthorizationCodeGrant(clientSettings);

    2. Call the BuildAuthorizationRequestPacketWithPKCE() method to build the fully qualified URL to redirect to the authentication endpoint.

    Code Block
    //Generate random nonce and state
    var nonce = Guid.NewGuid().ToString("N");
    var state = Guid.NewGuid().ToString("N");
    
    //Generate code_verifier
    var unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_`";
    Random random = new Random();
    var code_verifier = new string(Enumerable.Repeat(unreservedChars, 43).Select(s => s[random.Next(s.Length)]).ToArray());
    
    //Store the generated code_verifier in cookie for example
    CookieHelper.SetCookieData("OAuthCodeVerifier", code_verifier);
    
    //Generate code_challenge (if plain)
    //var code_challenge = code_verifier;
    //var code_challenge_method = "plain";
    
    //Generate code_challenge (if S256)
    var bytes = new SHA256CryptoServiceProvider().ComputeHash(Encoding.ASCII.GetBytes(code_verifier));
    var code_challenge = Convert.ToBase64String(bytes).Split('=')[0].Replace('+', '-').Replace('/', '_');
    var code_challenge_method = "S256";
    
    //Use the below code for "code" flow to build parameters
    var parameters = handler.BuildAuthorizationRequestPacketWithPKCE
    (ParameterFormat.FormUrlEncoded, state, null, nonce, code_challenge, code_challenge_method, null);
            
    //Use the below code for "code id_token" flow to build parameters
    //var responseTypes = new List<ResponseType> { ResponseType.id_token };
    //var parameters = handler.BuildAuthorizationRequestPacketWithPKCE
    //(ParameterFormat.FormUrlEncoded, state, "openid", nonce, code_challenge, code_challenge_method, responseTypes);
     
    //Generate redirect URL
    var redirectUrl = string.Format("{0}?{1}", clientSettings.AuthorizeUrl, parameters);

    3. In the application’s callback method AuthorizationCodeGrantWithPKCE() for example, extract the code ,state and the generated code_verifier , build an AuthorizationResponseModel model and send it to the GetAccessToken() method.

    Code Block
    public ActionResult AuthorizationCodeGrantWithPKCE(AuthorizationCodeGrantViewModel model)
    {
      AuthorizationResponseModel authorizationResponseModel = new AuthorizationResponseModel() {Code = "xxxxxxx", State = state};
      
      //Retrieve the code_verifier stored in the cookie
      var code_verifier = CookieHelper.GetCookieData("OAuthCodeVerifier");
      var additionalParams = new Dictionary<string, string>();
      additionalParams["code_verifier"] = code_verifier;
      
      AccessTokenResponseModel tokenResponseModel = null;
      try
      {
          tokenResponseModel = handler.GetAccessToken<AccessTokenResponseModel>(
              RequestMethod.POST,
              ParameterFormat.FormUrlEncoded,
              authorizationResponseModel,
              false,
              null,
              additionalParams);
      }
      catch {  //Handle error   }
    }
    Div
    stylefloat: left; position: fixed;

    IN THIS ARTICLE

    Table of Contents
    maxLevel4
    minLevel2
    stylenone

    Insert excerpt
    IL:External Stylesheet
    IL:External Stylesheet
    nopaneltrue