i-TegoDocumentationAuthentification > OpenID Connect OAuth Server dedicated > Develop > OpenID Connect > OpenID Connect : Authorization Code Grant

Authentication using the OpenID Connect authorization code flow Excerpt from the spécification

  publié le par DnC

This section explains how to perform authentication using the Authorization Code Flow.

The diagram opposite gives a more detailed idea of the continuation of the exchanges between the 3 poles of a authorization flow via a code. Click on the image to enlarge


The rest of this article is an excerpt from OpenID Connect Core 1.0 with our comments.

3.1. Authentication using the Authorization Code Flow.

This section describes how to perform authentication using the Authorization Code Flow. [1].

When using the Authorization Code Flow, all tokens are returned from the Token Endpoint [2].

The Authorization Code Flow returns an Authorization Code to the Client [3], which can then exchange it for an ID Token and an Access Token directly. This provides the benefit of not exposing any tokens to the User Agent and possibly other malicious applications with access to the User Agent. The Authorization Server can also authenticate the Client before exchanging the Authorization Code for an Access Token. The Authorization Code flow is suitable for Clients that can securely maintain a Client Secret between themselves and the Authorization Server.

3.1.1. Authorization Code Flow Steps

- The Authorization Code Flow goes through the following steps :
- Client prepares an Authentication Request containing the desired request parameters.
- Client sends the request to the Authorization Server.
- Authorization Server Authenticates the End-User.
- Authorization Server obtains End-User Consent/Authorization [4]
- Authorization Server sends the End-User back to the Client with an Authorization Code.
- Client requests a response using the Authorization Code at the Token Endpoint.
- Client receives a response that contains an ID Token and Access Token in the response body.
- Client validates the ID token and retrieves the End-User’s Subject Identifier.

3.1.2. Authorization Endpoint

The Authorization Endpoint performs Authentication of the End-User. This is done by sending the User Agent to the Authorization Server’s Authorization Endpoint for Authentication and Authorization, using request parameters defined by OAuth 2.0 and additional parameters and parameter values defined by OpenID Connect.

Communication with the Authorization Endpoint MUST utilize TLS. See Section 16.17 for more information on using TLS.

3.1.2.1. Authentication Request

An Authentication Request is an OAuth 2.0 Authorization Request that requests that the End-User be authenticated by the Authorization Server.

Authorization Servers MUST support the use of the HTTP GET and POST methods defined in RFC 2616 [RFC2616] at the Authorization Endpoint. Clients MAY use the HTTP GET or POST methods to send the Authorization Request to the Authorization Server. If using the HTTP GET method, the request parameters are serialized using URI Query String Serialization, per Section 13.1. If using the HTTP POST method, the request parameters are serialized using Form Serialization, per Section 13.2.

OpenID Connect uses the following OAuth 2.0 request parameters with the Authorization Code Flow :
- scope
REQUIRED. OpenID Connect requests MUST contain the openid scope value. If the openid scope value is not present, the behavior is entirely unspecified. Other scope values MAY be present. Scope values used that are not understood by an implementation SHOULD be ignored. See Sections 5.4 and 11 for additional scope values defined by this specification.

- response_type
REQUIRED. OAuth 2.0 Response Type value that determines the authorization processing flow to be used, including what parameters are returned from the endpoints used. When using the Authorization Code Flow, this value is code.

- client_id
REQUIRED. OAuth 2.0 Client Identifier valid at the Authorization Server.

- redirect_uri
REQUIRED. Redirection URI to which the response will be sent. This URI MUST exactly match one of the Redirection URI values for the Client pre-registered at the OpenID Provider, with the matching performed as described in Section 6.2.1 of [RFC3986] (Simple String Comparison). When using this flow, the Redirection URI SHOULD use the https scheme ; however, it MAY use the http scheme, provided that the Client Type is confidential, as defined in Section 2.1 of OAuth 2.0, and provided the OP allows the use of http Redirection URIs in this case. The Redirection URI MAY use an alternate scheme, such as one that is intended to identify a callback into a native application.

- state
RECOMMENDED [5]. Opaque value used to maintain state between the request and the callback. Typically, Cross-Site Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this parameter with a browser cookie.

OpenID Connect also uses the following OAuth 2.0 request parameter, which is defined in OAuth 2.0 Multiple Response Type Encoding Practices [OAuth.Responses] :

- response_mode
OPTIONAL. Informs the Authorization Server of the mechanism to be used for returning parameters from the Authorization Endpoint. This use of this parameter is NOT RECOMMENDED when the Response Mode that would be requested is the default mode specified for the Response Type.

This specification also defines the following request parameters :

- nonce
OPTIONAL. String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token. Sufficient entropy MUST be present in the nonce values used to prevent attackers from guessing values. For implementation notes, see Section 15.5.2.

- display
OPTIONAL. ASCII string value that specifies how the Authorization Server displays the authentication and consent user interface pages to the End-User. The defined values are :

  • page
    The Authorization Server SHOULD display the authentication and consent UI consistent with a full User Agent page view. If the display parameter is not specified, this is the default display mode.
  • popup
    The Authorization Server SHOULD display the authentication and consent UI consistent with a popup User Agent window. The popup User Agent window should be of an appropriate size for a login-focused dialog and should not obscure the entire window that it is popping up over.
  • touch
    The Authorization Server SHOULD display the authentication and consent UI consistent with a device that leverages a touch interface.
  • wap
    The Authorization Server SHOULD display the authentication and consent UI consistent with a "feature phone" type display.

- prompt
OPTIONAL. Space delimited, case sensitive list of ASCII string values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent. [6]

The defined values are :

  • none
    The Authorization Server MUST NOT display any authentication or consent user interface pages. An error is returned if an End-User is not already authenticated or the Client does not have pre-configured consent for the requested Claims or does not fulfill other conditions for processing the request. The error code will typically be login_required, interaction_required, or another code defined in Section 3.1.2.6. This can be used as a method to check for existing authentication and/or consent. [7]
  • login
    The Authorization Server SHOULD prompt the End-User for reauthentication. If it cannot reauthenticate the End-User, it MUST return an error, typically login_required.
  • consent
    The Authorization Server SHOULD prompt the End-User for consent before returning information to the Client. If it cannot obtain consent, it MUST return an error, typically consent_required.
  • select_account
    The Authorization Server SHOULD prompt the End-User to select a user account. This enables an End-User who has multiple accounts at the Authorization Server to select amongst the multiple accounts that they might have current sessions for. If it cannot obtain an account selection choice made by the End-User, it MUST return an error, typically account_selection_required.

The prompt parameter can be used by the Client to make sure that the End-User is still present for the current session or to bring attention to the request. If this parameter contains none with any other value, an error is returned.

- max_age
OPTIONAL. Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End-User was actively authenticated by the OP. If the elapsed time is greater than this value, the OP MUST attempt to actively re-authenticate the End-User. (The max_age request parameter corresponds to the OpenID 2.0 PAPE [OpenID.PAPE] max_auth_age request parameter.) When max_age is used, the ID Token returned MUST include an auth_time Claim Value.

- ui_locales
OPTIONAL. End-User’s preferred languages and scripts for the user interface, represented as a space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. For instance, the value "fr-CA fr en" represents a preference for French as spoken in Canada, then French (without a region designation), followed by English (without a region designation). An error SHOULD NOT result if some or all of the requested locales are not supported by the OpenID Provider.

- id_token_hint
OPTIONAL. ID Token previously issued by the Authorization Server being passed as a hint about the End-User’s current or past authenticated session with the Client. If the End-User identified by the ID Token is logged in or is logged in by the request, then the Authorization Server returns a positive response ; otherwise, it SHOULD return an error, such as login_required. When possible, an id_token_hint SHOULD be present when prompt=none is used and an invalid_request error MAY be returned if it is not ; however, the server SHOULD respond successfully when possible, even if it is not present. The Authorization Server need not be listed as an audience of the ID Token when it is used as an id_token_hint value.
If the ID Token received by the RP from the OP is encrypted, to use it as an id_token_hint, the Client MUST decrypt the signed ID Token contained within the encrypted ID Token. The Client MAY re-encrypt the signed ID token to the Authentication Server using a key that enables the server to decrypt the ID Token, and use the re-encrypted ID token as the id_token_hint value.

- login_hint
OPTIONAL. Hint to the Authorization Server about the login identifier the End-User might use to log in (if necessary). This hint can be used by an RP if it first asks the End-User for their e-mail address (or other identifier) and then wants to pass that value as a hint to the discovered authorization service. It is RECOMMENDED that the hint value match the value used for discovery. This value MAY also be a phone number in the format specified for the phone_number Claim. The use of this parameter is left to the OP’s discretion.

- acr_values
OPTIONAL. Requested Authentication Context Class Reference values. Space-separated string that specifies the acr values that the Authorization Server is being requested to use for processing this Authentication Request, with the values appearing in order of preference. The Authentication Context Class satisfied by the authentication performed is returned as the acr Claim Value, as specified in Section 2. The acr Claim is requested as a Voluntary Claim by this parameter.

Other parameters MAY be sent. See Sections 3.2.2, 3.3.2, 5.2, 5.5, 6, and 7.2.1 for additional Authorization Request parameters and parameter values defined by this specification.

Notes

[1From the beginning, the reconciliation of the terms "authentication" and "authorization" creates confusion. Did you read : Généralités sur l’authentification, introduction d’OpenID Connect ?

[2that is, tokens only run in a server-to-server relationships

[3the client application, not to be confused with the browser of the end user or "user agent".

[4All of OpenID Connect’s phraseology is determined by a particular use case : the one where the end user owns the data held by the resource server and which the application wants to access. However, OpenID Connect can also be used to authenticate the end user and allow them to access resources that they do not own. In this case, the notion of authorization is reversed : it is the owner of the application and protected resources that grants access.

[5Required for OAuthSD

[6In reality, not all combinations are allowed or do not make sense. OAuthSD will interpret : ’none’, ’login’, ’login consent’, ’consent’.

[7The prompt = ’none’ declaration is used in particular for the Silent Re-authentication procedure and the monitoring of the validity of the session by iframe. See : SSO et connexion unique (Single Login Identification, SLI),OpenID Connect Session Management and Monitoring de l’état de l’authentification et SLO.

Identifying the end user

  publié le par DnC

Identification is the part of the authentication in which the end user identifies or is identified. OAuthSD offers everything necessary to process identification (login / password, two-factor identification) or may delegate this identification to a third-party Identity Provider.

Integrated identification systems at OAuthSD

OAuthSD distinguishes primary identity providers and, if two-factor identification (2FA) is enabled, the secondary ones. The IDENTITY_PROVIDER and TFA_PROVIDER configuration constants define which systems will be used.

OAuthSD offers the following identification systems :

- Primary identification (constant IDENTITY_PROVIDER) :

  • ’password’ : classic identification by login and password,
  • ’ghostkeys’ : identification by login and password clicked in a random grid.

- Secondary identification (constant TFA_PROVIDER) :

  • ’checkbysms’ : the classic SMS check,
  • ’gangsta’ : TOTP type identification (Time-based One-time Password) with Google Authenticator (DnC’s own is under development).
    (more to come ...)

Learn more :
- Validation en 2 étapes (Two Factor Authentication, 2FA) .

Delegate identification to third party ID providers

One easy way is to use the identity services of Google, Facebook, Twitter etc. This certainly provides great comfort for the user and perfectly illustrates the principle of SSO.
However, this is not the way to ensure the confidentiality that you want in an organization implementing protected information that belongs to it. Allowing a user to simultaneously connect to a social network and business applications in the organization with the same tracking cookie is certainly the worst of all data protection.

OAuthSD allows integration of third-party identification systems, whether standard such as LADP and Active Directory (Kerberos) or organization-specific (ID card, biometric identification ...). Such a system can substitute for both primary and secondary identification.

Learn more :
- Identification par OpenID Connect des utilisateurs identifiés avec Kerberos.

OpenID Connect : Get an authorization for the client application

  publié le par DnC

As part of the Authorization Code Flow, the end-user’s user-agent (usually a web browser) is redirected to the Authorization Endpoint , to allow it to identify itself and grant permissions to the client application.
If successful, the user-agent will be redirected to Endpoint Token with an authorization code.

Authorization Endpoint)

https://oa.dnc.global/authorize

Request

Here are some examples :
PHP

  1.     $data = array(
  2.         'response_type' => 'code',
  3.         'client_id' => 'chemin_openid',
  4.         'state' =>  $oauth_state,
  5.         'scope' => 'openid profile',
  6.     );
  7.  
  8. $authorization_endpoint = 'https://oa.dnc.global/authorization';
  9.  
  10. $authorization_endpoint .= '?' . http_build_query($data);
  11.     header('Location: ' . $authorization_endpoint);
  12.     exit();

Télécharger

SPIP

  1.     include_spip('inc/headers');
  2.    
  3.     $oauth_state = session_get('oauth_state');
  4.     $url = "http://oa.dnc.global/authorize?response_type=code&client_id=chemin_openid&scope=openid profile&redirect_uri=http://chemindeleau.com/callback_openid.php&state=$oauth_state";
  5.    
  6. redirige_par_entete($url);

Télécharger

Notes :
- To obtain an identity token, the scope must include "openid". Otherwise, the answer will be identical to that of the OAuth 2.0 protocol, and will therefore only include the access token.
- To obtain a Refresh Token, the scope must have "offline_access".
- Although the "standard" indicates that the redirect_uri parameter is mandatory, it can be omitted if the client application has been registered with only one return address.
- If the client application has been registered with multiple return addresses, the redirect_uri parameter is required, and must be one of them.
- It is possible to add to the URL any useful parameter, such as a session identifier. These will be retransmitted into the body of the answer, almost completely.
- Before it can interact in an OpenID Connect stream, the author must register the client application on the OAuthSD with the parameters expected by OpenID Connect.
- It is the responsibility of the client application to ensure the good form and security of the values ​​transmitted by the URL parameters.

End User Authentication

At the call of the authorization endpoint :
- the OAuthSD server redirects the user-agent to the authentication page(s) (we stay in the domain of the authorization server).
- the end user authenticates in this page (the identifiers are therefore confined to the server).
- the server posts the authorization code to the redirection endpoint.

Back to the client application

If successful, the server redirects the browser to the redirection endpoint in the client application (HTTP header code 302). This URI is defined by the author of a client application when it is registered on this server. See : OpenID Connect : Lier une application cliente au serveur OAuthSD.

The code and state parameters are passed in the URL. Example :

http://chemindeleau.com/callback_openid.php?code=3159339c2f1326f9fa128e161b8387feca690b65&state=98b3027139f7cb3be4a885d7c81b41bb

It is the responsibility of the client application to ensure its security vis-à-vis the values transmitted by the URL parameters.

Error situations

Refer to : API OpenID Connect : Point d’extrémité d’autorisation (Authorization Endpoint).

OpenID Connect : get access tokens

  publié le par DnC

We are in the case of Authorization Code flow.

The client application must have an access token to obtain protected data from a resource server. The necessary code is entirely the responsibility of the author of the client application, in response to redirection on the URI of the redirection endpoint.

To obtain the access tokens, a client application addresses the token endpoint with the code obtained in the authorization phase.

Token Endpoint

https://oa.dnc.global/token

More details : API OpenID Connect : Point d’extrémité d’autorisation (Authorization Endpoint).

The token endpoint is the endpoint on the authorization server that the client application is addressing with the authorization code.

Access Token Request Form

The request must be made only by the POST method.

For authentication of the client application to the authorization server, OAuthSD imposes the client_secret_basic method. Authentication is therefore performed using HTTP Basic authentication (see section 2.3.1 of OAuth 2.0 [RFC6749]). The identifiers client_id and client_secret are those that were defined during the registration of the client application on the server.

The following parameters must be posted :
- grant_type : Authorization flow type, must be "authorization_code".
- code : the authorization code received.
- redirect_uri : the return address to the client application.

Server response

If successful, the server returns an HTTP 200 response. The body of the response contains :

index type valeur
page JSON array access_token : (string) OAuth 2.0 access token
expires_in : (long) lifetime in secondes
token_type : (string) "Bearer"
scope : (string) "openid ... "
id_token : (string) ID token (JWT)

The Header includes, as it should, the ’Cache-Control : no-cache, no-store’ directive.
 

If unsuccessful, the body of the response contains :

index type valeur
page JSON Array error : error title,
error_description : error description

La réponse HTTP ainsi que les valeurs de error et error_description sont décrites ici : API OpenID Connect : Point d’extrémité de jeton (Token Endpoint).

Request the refresh token

OpenID Connect only returns a Refresh Token, together with the access token, if the scope "offline_access" was included in the request and accepted, which will only happen with the authorization flow via a code (Authorization Code Grant).

Code examples

Query data :
- $authcode is the authorization code obtained in the previous step and sent to the CallBack page
- $client_id, $client_secret : As indicated when registering the client application on the authorization server.

PHP

  1. // Request an access token for the application
  2.  
  3.     $url = 'http://oa.dnc.global/token';
  4.  
  5.     $datas =  array(
  6.         'grant_type' => 'authorization_code',
  7.         'code' => $authcode,
  8.         'redirect_uri' => 'http://chemindeleau.com/callback_openid.php',
  9.         'client_id' => 'chemin_openid',
  10.         'client_secret' => '01fc458',    
  11.     );        
  12.  
  13.     $ch = curl_init();
  14.  
  15.     curl_setopt($ch, CURLOPT_URL, $url);
  16.     curl_setopt($ch, CURLOPT_POST, true);
  17.     curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
  18.     curl_setopt($ch, CURLOPT_POSTFIELDS,  http_build_query($datas));
  19.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  20.     curl_setopt($ch, CURLOPT_HEADER, false);
  21.     curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  22.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  23.  
  24.     $result_json = curl_exec($ch);
  25.     curl_close($ch);
  26.  
  27.     $result = json_decode($result_json, true);
  28.     $access_token = $result['access_token'];  // Access Token
  29.     $id_token = $result['id_token'];                    // ID Token (JWT)

Télécharger

Authentication can also be passed in the Header like this :

  1.     $datas =  array(
  2.         'grant_type' => 'authorization_code',
  3.         'code' => $sanitized_authcode,
  4.         'redirect_uri' => 'http://chemindeleau.com/callback_openid.php',
  5.     );
  6.    
  7.     $client_id = 'chemin_openid';
  8.     $client_secret = '01fc458';  
  9.  
  10.     $ch = curl_init();
  11.     curl_setopt($ch, CURLOPT_URL, $url);      
  12.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  13.     curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  14.     curl_setopt($ch, CURLOPT_USERPWD, "{$client_id}:{$client_secret}");
  15.     curl_setopt($ch, CURLOPT_POST, true);
  16.     curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
  17.     curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($datas));
  18.     curl_setopt($ch, CURLOPT_HEADER, false);
  19.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Télécharger

SPIP

  1.         $url = 'http://oa.dnc.global/oauth/token.php';
  2.         $options = array(
  3.             'method' => 'POST',
  4.             'datas' =>  array(
  5.                  'grant_type' => 'authorization_code',
  6.                  'code' => $authcode,
  7.                  'redirect_uri' => 'http://chemindeleau.com/callback_openid.php',
  8.                  'client_id' => 'chemin_openid',
  9.                  'client_secret' => '01fc458',  
  10.             )        
  11.         );
  12.  
  13.         $res = recuperer_url($url, $options);
  14.  
  15.         $page = json_decode($res['page'], true);
  16.  
  17.         $token = $page['access_token'];
  18.         $id_token = $page['id_token'];

Télécharger

id_token_hint : Silent Re-authentication of subject with ID Token

  publié le par DnC

Authenticating subject with ID Token is an option of OpenID Connect Authorization code flow.
To fulfill the OpenID Connect certification, it is necessary to complete the test "OP-Req-id_token_hint".
The Brent Shaffer’s oauth2-server-php library does’nt process id_token_hint. OAuthSD will take care of it.

The use case consist to call Authorize using prompt=none and passing ID Token in id_token_hint parameter.

The specification states :

id_token_hint
OPTIONAL. ID Token previously issued by the Authorization Server being passed as a hint about the End-User’s current or past authenticated session with the Client. If the End-User identified by the ID Token is logged in or is logged in by the request, then the Authorization Server returns a positive response ; otherwise, it SHOULD return an error, such as login_required. When possible, an id_token_hint SHOULD be present when prompt=none is used and an invalid_request error MAY be returned if it is not ; however, the server SHOULD respond successfully when possible, even if it is not present. The Authorization Server need not be listed as an audience of the ID Token when it is used as an id_token_hint value.

OAuthSD Implementation of id_token_hint processing

If the call to Authorize includes the id_token_hint parameter, we will verify the JWT signature. If Ok, we will adopt the sub claim for user_id and continue normally with prompt = none processing.

The phrase "or is connected by the request" may cover a mechanism such as silent reauthentication (SRA). This is what OAuthSD do : the process is then to extend the OIDC session, ie refresh the SLI cookie, whether the user is logged in or not.
The authorize controller will respond with an authorization code, and the application will re-request the tokens, which will cause the access token to refresh.
Thus, the user will be (re)connected, seen from the server, for the full lifetime of the new access token. we will not place much trust in this method, so acr_value will be set to 1.

The administrator can control the process with REAUTHENTICATE_BY_ID_TOKEN and DO_SRA_ON_ID_TOKEN configuration constants (set by default to true).

Security note

When you do an authentication with prompt = ’none’, you should always include id_token_hint. More precisely, querying Authorize with prompt = ’none’ without id_token_hint can not be considered as an end-user authentication, but as a simple information on the declared user connection.

Notes :
- If user_id is enforced by client registration, the ID Token sub claim should be identical, or the process will fail.
- Prompt = ’none’ excludes prompting of user. The expression "or is logged in by the request" may cover such mechanism as Silent Re-Authentication (SRA). It is what OAuthSD allows to do.

See also :
- OpenID Connect : SSO, session management etc..