Preliminary
The Authentication France API allows you to authenticate Orange France mass market customers on your service/client using OpenID Connect Core 1.0 protocol. Once implemented, your service/client will benefit from the full power and security of Orange France authentication, including its future evolutions.
This document provides quick links to the following contents:
- List of available resources
- List of supported use cases
- Compliancy with standards
- Discover configuration metadata
- Authenticating the end-user and federating the IDs
- Tokens lifecycle / Refresh tokens
- ID Token validation
- Get authorizations for accessing protected API resources
- List of errors
List of available resources
Resources are provided by Group PAPRICA OpenID provider that is connected with Orange France identity provider (i.e. uSSO/Wassup platform).
Resources are available from Internet network only, using the endpoints provided in the following sub-sections.
If you don't have an Orange end-user account, or you need account management help, please refer to the following guides:
- how to create Orange user accounts for developers
- how to manage Orange user accounts using Orange selfcare
1/ OpenID Connect Core API
The OpenID Connect Core API allows Relying Parties to delegate the authentication of Orange France mass market customers towards PAPRICA/OFR OpenID Provider, to obtain thir consent and retrieve claims related to user's identity ('sub' only). |
resources - Authorization endpoint [GET,POST]: https://api.orange.com/openidconnect/fr/v1/authorize - Token endpoint [POST]: https://api.orange.com/openidconnect/fr/v1/token - Userinfo endpoint [GET,POST]: https://api.orange.com/openidconnect/fr/v1/userinfo
2/ Discovery API
The Discovery API allows Relying Parties to retrieve configuration metadata from PAPRICA/OFR OpenID Provider (e.g. Authorization/Token/Userinfo/JWKS URIs, signing algorithms, authentication methods, etc.). |
resources - Discovery endpoint [GET]: https://api.orange.com/openidconnect/fr/v1/.well-known/openid-configuration
3/ JKWS API
The JKWS API allows Relying Parties to get access to public cryptographic key that is required check the integrity of the ID tokens issued by PAPRICA/OFR OpenID Provider.
resources - JWKS endpoint [GET]: https://api.orange.com/openidconnect/fr/v1/jwks
List of supported use cases
The Authentication France API is mainly designed for identity federation (i.e. end-user authentication delegation) purpose.
It relies on OpenID Connect protocol that allows clients to verify the identity of the end-user based on the authentication performed by our PAPRICA/OFR (INT) authorization server (thanks to uSSO/Wassup (TB1) identity provider) as well as to obtain basic profile information about the end-user.
Compliancy with standards
1/ OpenID Connect Core 1.0 standard
This Authentication France API relies on capabilities provided by the OpenID Connect Core 1.0 standard.
OpenID Connect combines authentication and authorization, and allows you to verify the identity of the end-user while authorizing them. All information regarding OpenID Connect can be found at http://openid.net/connect.
Orange implementation is in line with the OpenID Connect Basic Client Implementer’s Guide. The only difference is the "state" parameter which is mandatory in our implementation for security reasons (see RFC6819 section-5.3.5).
a/ OpenID Connect scopes for Identity federation use cases
OpenID Connect Clients use scope values, as defined in Section 3.3 of OAuth 2.0 [RFC6749], to specify what access privileges are being requested for access tokens. The scopes associated with access tokens determine what resources will be available when they are used to access OAuth 2.0 protected endpoints like Userinfo endpoint.
For OpenID Connect, scopes can be used to request that specific sets of information be made available as claim values.
OpenID Connect defines the following scope values that are used to request claims:
Scopes | Description |
---|---|
openid | Used to request access to the ID token that embeds the end-user identifier (ISE2 or GID) for identity federation. |
profile | Used to request access to the end-user's default profile claims (e.g. name, family_name, given_name). |
Used to request access to the email and email_verified claims. | |
phone | Used to request access to the phone_number and phone_number_verified claims. |
WARNING: PAPRICA/OFR platform is supporting the 'openid' scope value only. Thus, the GET /userinfo request will return the 'sub' claim value only.
2/ OpenID Connect Discovery 1.0 standard
The Discovery API is compliant with OpenID Connect Discovery 1.0 standard. It defines a JSON document that provides access to any relevant OpenID Provider's configuration metadata, including all necessary endpoints and public key location information.
These configutaion metadata are mainly issued from the following OpenID Connect final specifications:
- OpenID Connect Core 1.0: https://openid.net/specs/openid-connect-core-1_0.html
- OpenID Connect Discovery 1.0: https://openid.net/specs/openid-connect-discovery-1_0.html
However, additional metadata may exist, especially those defined by other OpenID Connect draft specifications like:
- OpenID Connect Session Management 1.0: https://openid.net/specs/openid-connect-session-1_0.html
- OpenID Connect Front-Channel Logout 1.0: https://openid.net/specs/openid-connect-frontchannel-1_0.html
- OpenID Connect Back-Channel Logout 1.0: https://openid.net/specs/openid-connect-backchannel-1_0.html
a/ Certified implementations
OpenID Connect/OAuth 2.0 certified implementations/libraries implementations support the OpenID Connect Discovery 1.0 specification.
For example, the Apache 2.x mod_auth_openidc module. The 'auth_openidc.conf' configuration file supports the 'OIDCProviderMetatadata' configuration parameter that must be set with the PAPRICA/OFR OP's discovery endpoint URL. Other parameters exists to set the technical information that will be required by the RP to all the steps of the OAuth 2.0 flow, namely the client_id identifier with its secret, the RP callback URI for the response of the Authorization request, etc.
As an example:
OIDCProviderMetadataURL https://api.orange.com/openidconnect/fr/v1/.well-known/openid-configuration
OIDCClientID be9bc6a1-xxxx-yyyy-zzzz-24a209fd4e7c
OIDCClientSecret **********************
# OIDCRedirectURI is a vanity URL that must point to a path protected by this module but must NOT point to any content
OIDCRedirectURI https://myservice.orange.fr/oauth2/redirect
<Location /secure>
AuthType openid-connect
Require valid-user
</Location>
3/ JKWS, JWK, JWA standards
a/ JSON Web Key Set (JWKS)
As defined by https://tools.ietf.org/html/rfc7517, a JSON Web Key Set (JWKS) is a JSON document that represents a set of cryptographic keys (typically RSA or EC) in JWK format.
As an example: a JWKS JSON document with two public keys (RS256, EC384)
{
"keys": [{
"kty": "RSA",
"kid": "eGq63W62fLOEqRwXr5SQatMkVZ65LV4AUVf1_mzQrMM",
"n": "r_wfT0MCZ9ou9JEjaxRQZApnMtgbbeZq73gtj5QeYs-_UcvO549E7XKRw2xMy7NAdzSTqLED_kzUrPsYpoX_MSLOIGt124JKhPBk2qOYgexQBm4qg_MkiMrDtCw3fEsrQvUds_-kwuQiZGaQO5xpwDzNILwl9GOU-c3FtAXIJMIu-vTNh9x9P7Y-9d1EPL_FfzI413Rdah_HkFUyXimtF3jpPjdrdCZ5Mw_hdOeojJ-Hv9FuwDYhOOpyL_8WwRZzQMNh8V1E5jONEl76NZ4SWWYvbalDw2StUU9NEveRlXJfKYzml4KQUgsW8wPNhquPG1Nf6dWExnp8CPs25e0Lc7ticWtGuGxLTrVaV09fxfrBHr4EC27eZ-EXahhsseloseDs9sUBiZLVOVa82Fs24lyklZynaz1dA7NEM9kduOWKq5UAZygcXBYVLMWw4cQUMCbCRIHQSvSAqV8Dk1hBxuMsHkP1C7aXqN6pUmaKQ2nO7TNNNrVDotb64bWSR96Nhu2ZKg5Ez1gn2UiT_6n4Zbo61CMYN6vBFIXFoVoByYH7VL6_VUIzOUx2BFmI1IzwaKfFfv2SDTAchNdMaFmsAX0Z63wYla04_GU00DITnP_zkA8vbbyRdXiQycAlPEzgyiH0TAUEyru3NcPXHyJUASNEMdP0X43FZJsESf6apSs",
"e": "AQAB"
}, {
"kty": "EC",
"kid": "wIlL0oR5-8kbyLykj4rZhH561GifjyyuL0o6yFNSkVk",
"crv": "P-384",
"x": "nAYBgwiWIkYgsgkoggopXnuzKQgKnfloPAao6j1IZC7DnOiYzHZfjx1incOpmZTz",
"y": "2o4tr22767V78MayF4sE63Ljq-VMVlP9uHL6gwRJu6iv3Nr1XkzwwP9xGfx_8huM"
}]
}
TIPS: the JWKS JSON document is made available using a JWKS URI(e.g. https://api.orange.com/openidconnect/fr/v1/jwks) that can be retrieved using the PAPRICA/OFR OP's Discovery API. Typical usage of public key is the validation of ID tokens issued by PAPRICA/OFR OP.
b/ JSON Wek Key (JWK)
As defined by https://tools.ietf.org/html/rfc7517, a JSON Web Key (JWK) is a JSON data structure that represents a cryptographic key (typically RSA or EC). These keys can be either asymmetric or symmetric, and they can hold both public and private information about the key.
As examples:
Sample #1: RSA (RS256) private key
{
"kty": "RSA",
"n": "q21s7KxUIk4Od8YhymUGb8xDKTj_D3JDYEAII9EER4AMIXbRB1wQ6zrC0V_U/../tuAmUrV3vqW4TUpkByX5Tye-1--rW96ddvd8ap_-orKqmc9iEMvansR0UN6BYoFebQKJj-sxp8w",
"e": "AQAB",
"d": "Jomh_A69lzyu-fQbspFFgiqMSp8aj9FjHicm7U5WxPAfSgKY-SuUTh1WoJUH/../Cngx9tp0xkYFJo3zBAfgfOLBoim0TqfbjHK5PsuQPe0fpdJEhdKNLaeSMWW21zWW2ziwFxBpO_Iel0pYbnMwrJJHRYuq_7UyECGQ",
"p": "1A_3y09UzFKiOiqwyHanMdlsz3yJenrPny7m6oiMYn_V8FXoI8vJ9LguGr45/../HIb1_-jD2lcNHbSx7IWMF0Qjlsrg4Uy1Ol31M_YNzYhbihi00wVKfdefl4-RFU",
"q": "zvIiUvHFX_rFxXyaGhB0MfZVQxuoj_x2E54GGXIIjFSBSeo8-NuJ8aiy9G7r/../xoHHSQ1UxnQAFgAzjLuKjB81THBjaiFAZ6XAeToN3hd93MQwdP7UczkpEao_Sc",
"dp": "Iswj-yafYY_FswnCTIK72MA2zK1A2epBG3vUxHN3pcoYTwGpwAX2s8NtPVI/../1kaHI2EMkk1qh49ZCti3LjIuLNZJpG6z5kn4rHgZt7pCWxzGv0HFAXVaaMJUKk",
"dq": "zWH9srgEHRdyxGa_QfLmftdtEycWCaCTRzDj-Mj1tt__WG5CiPDJXK8CvBi/../wUb3k4bJhhOGKk-U2a0e-aXXbb90ytWpZ7RW63k0XiCOZ1XGibaG_rvSCJggK0",
"qi": "AveY6awTjAnuqRA1F5hBiQ1ks6gaCrRqJfecybdj3dt6AKx3nCWSucdsRaJ/../o4ZFFDlIBuZXZeYINSUtM5suWOKQgRy0H-wcm6cmZZNXAlMXSQpoMNzEyf_QBY",
"kid": "sFXa-BPYtbCLWk2aeycb9HTM701AATKMZKsn9ss1OUU",
"use": "sig",
"alg": "RS256"
}
Sample #2: RSA (RS256) public key
{
"kty": "RSA",
"n": "q21s7KxUIk4Od8YhymUGb8xDKTj_D3JDYEAII9EER4AMIXbRB1wQ6zrC0V_U/../tuAmUrV3vqW4TUpkByX5Tye-1--rW96ddvd8ap_-orKqmc9iEMvansR0UN6BYoFebQKJj-sxp8w",
"e": "AQAB",
"kid": "sFXa-BPYtbCLWk2aeycb9HTM701AATKMZKsn9ss1OUU",
"use": "sig",
"alg": "RS256"
}
c/ JSON Wek Algorithm (JWA)
JWKs can represent RSA or Elliptic Curve (EC) private/public keys.
The section 4 of the https://tools.ietf.org/html/rfc7517 specification define the common parameters of a key.
kty
(required): identifies the cryptographic algorithm family used with the key. E.g. 'RSA'.use
(optional): identifies the intended use of the public key. The "use" parameter is employed to indicate whether a public key is used for encrypting data or verifying the signature on data. E.g. 'sig'.alg
(optional): identifies the algorithm intended for use with the key. E.g. RS256, ES384.kid
(optional): used to mach a specific key. E.g. sFXa-BPYtbCLWk2aeycb9HTM701AATKMZKsn9ss1OUU.
The section 6.3.1 of the https://tools.ietf.org/html/rfc7518 specification define the specific parameters of a public RSA key.
n
: the modulus value for the RSA public key. It is represented as a Base64urlUInt-encoded value. E.g. q21s7KxUIk4Od8YhymUGb8xDKTj_D3JDYEAII9EER4AMIXbRB1wQ6zrC0V_U/../tuAmUrV3vqW4TUpkByX5Tye-1--rW96ddvd8ap_-orKqmc9iEMvansR0UN6BYoFebQKJj-sxp8we
: the exponent value for the RSA public key. It is represented as a Base64urlUInt-encoded value. E.g. AQAB
Retrieve configuration metadata
PAPRICA/OFR OP makes available a JSON document at the path formed by concatenating the string /.well-known/openid-configuration to its Issuer URI. This document provides access to the OpenID/OAuth 2.0 endpoints, supported scopes and claims, public keys used to sign the tokens, and other details.
In production environment, the Discovery endpoint URL is: https://api.orange.com/openidconnect/fr/v1/.well-known/openid-configuration
OpenID Provider metadata
PAPRICA/OFR OP's directory API (PROD) provides access to the following core configuration metadata:
metadata | constraint | description | samples |
---|---|---|---|
issuer | REQUIRED | URL using the https scheme with no query or fragment component that the OP asserts as its Issuer identifier | https://open-id.orange.fr |
authorization_endpoint | REQUIRED | URL of the PAPRICA/OFR OP's OAuth 2.0 Authorization endpoint | https://api.orange.com/openidconnect/fr/v1/authorize |
token_endpoint | REQUIRED | URL of the PAPRICA/OFR OP's OAuth 2.0 Token endpoint | https://api.orange.com/openidconnect/fr/v1/token |
userinfo_endpoint | RECOMMENDED | URL of the PAPRICA/OFR OP's UserInfo endpoint | https://api.orange.com/openidconnect/fr/v1/userinfo |
jwks_uri | REQUIRED | URL of the PAPRICA/OFR OP's JSON Web Key Set [JWK] document. This contains the signing key(s) the client uses, for instance, to validate ID token signature | https://api.orange.com/openidconnect/fr/v1/jwks |
scopes_supported | RECOMMENDED | JSON array containing a list of the OAuth 2.0 scope values that the PAPRICA/OFR OP supports | ["openid"] |
response_types_supported | REQUIRED | JSON array containing a list of the OAuth 2.0 response_type values that the PAPRICA/OFR OP supports | ["code"] |
grant_types_supported | OPTIONAL | JSON array containing a list of the OAuth 2.0 Grant Type values that the PAPRICA/OFR OP supports | ["authorization_code"] |
acr_values_supported | OPTIONAL | JSON array containing a list of the Authentication Context Class References that the PAPRICA/OFR OP supports | [] |
subject_types_supported | REQUIRED | JSON array containing a list of the Subject Identifier types that the PAPRICA/OFR OP supports. The 'public' vakue means that the same subject ('sub') value is returned to all clients | ["public", "pairwise"] |
display_values_supported | REQUIRED | JSON array containing a list of user interface display types for the Authentication and Consent flow | ["page"] |
id_token_signing_alg_values_supported | REQUIRED | JSON array containing a list of the JWS signing algorithms supported by the PAPRICA/OFR OP for securing the issued ID tokens. In production, RS256 algorithm is used by default | ["HS256", "RS256"] |
token_endpoint_auth_methods_supported | OPTIONAL | JSON array containing a list of Client Authentication methods supported by the PAPRICA/OFR OP's OAuth 2.0 Token endpoint. | ["client_secret_post", "client_secret_basic"] |
claims_supported | RECOMMENDED | JSON array containing a list of the Claim Names of the Claims that the PAPRICA/OFR OP may be able to supply values for | ["sub", "iss", "auth_time", "acr"] |
request_parameter_supported | OPTIONAL | Boolean value specifying whether the PAPRICA/OFR OP supports use of the request parameter, with true indicating support | false |
request_uri_parameter_supported | OPTIONAL | Boolean value specifying whether the PAPRICA/OFR OP supports use of the request_uri parameter, with true indicating support | false |
ui_locales_supported | OPTIONAL | JSON array containing a space separated list of user preferred languages and scripts for the UI (as per RFC5646) | ["fr", "en"] |
Configuration metadata request
The PAPRICA/OFR OP Configuration document is queried using an HTTP GET request at the previously specified URI path.
No client authentication is required (e.g. HTTP Basic Authentication, mTLS authencation). However, TLS protocol is required to protect against information disclosure and tampering.
As an example:
curl --request GET --verbose \
--header "Accept: application/json" \
https://api.orange.com/openidconnect/fr/v1/.well-known/openid-configuration
Configuration metadata successfull response
A successful response use the 200 OK HTTP status code and return a JSON object using the application/json content type that contains a set of Claims as its members that are a subset of the Metadata values defined above.
As an example:
{
"issuer": "https://openid.orange.fr",
"authorization_endpoint": "https://api.orange.com/openidconnect/fr/v1/authorize",
"token_endpoint": "https://api.orange.com/openidconnect/fr/v1/token",
"userinfo_endpoint": "https://api.orange.com/openidconnect/fr/v1/userinfo",
"jwks_uri": "https://api.orange.com/openidconnect/fr/v1/jwks",
"scopes_supported": ["openid"],
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"acr_values_supported": [],
"subject_types_supported": ["public", "pairwise"],
"id_token_signing_alg_values_supported": ["HS256", "RS256"],
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
"token_endpoint_auth_signing_alg_values_supported": ["ES384"],
"display_values_supported": ["page"],
"claims_supported": ["sub", "iss", "auth_time", "acr"],
"ui_locales_supported": ["fr", "en"],
"request_uri_parameter_supported": false,
"request_parameter_supported": false
}
Configuration metadata error response
An error response uses the applicable HTTP status code value. The following error cases are managed by PAPRICA/OFR OP.
- The requested resource doesn't exist
- An internal server error has occurred. Contact Orange Developer support team
As an example, when using an invalid URI (i.e. /openid-config instead of /openid-configuration).
curl --request GET --verbose \
--header "Accept: application/json" \
https://api.orange.com/openidconnect/fr/v1/.well-known/openid-config
HTTP/1.1 404 Not Found
Date: Fri, 29 Oct 2021 09:39:01 GMT
Content-Length: 82
X-OAPI-Request-Id: opapccballrt02-12223-79290596-1
{
"error": "invalid_request",
"error_description": "The requested URI does not exist."
}
Authenticating the end-user and federating the IDs
1/ Send the Authentication/Authorization request to PAPRICA/OFR OpenID Provider
In order to obtain OpenID Connect/OAuth tokens, you first need to request an "authorization code" as defined in OAuth 2.0 and OpenID Connect. At this stage, PAPRICA/OFR OP first needs to authenticate the end-user and get authorizations before releasing the "authorization code".
To authenticate the end-user and obtain his/her consent, a GET or POST request must be sent to the PAPRICA/OFR OP's authorization endpoint by adding the following mandatory parameters (in query string or body part depending on HTTP method being used):
response_type
(required): the response type. Fixed: code.client_id
(required): the unique ID provided by Orange Developer portal to identify your service/client.scope
(required): a space delimited list of scope values (Caution: url-encoded space (%20) is required) that tells PAPRICA/OFR OP what kind of permissions your service/client needs. For instance: afi_admin%20anoo_manager.redirect_uri
(required): the callback URL you provided for your service/client when onboarding with PAPRICA/OFR OP. Note that it is mandatory for security reasons.state
(required): an 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.
NOTE: Please consult OWASP web site for further details about CSRF prevention: https://owasp.org/www-project-cheat-sheets/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
Additional optional parameters can be added to the Authorization request:
prompt
(optional): you can set this parameter in case you want to force the login and/or the consent page display. It can be useful if for example, your terms have changed and you want the end-user to revalidate the consent page. Multiple values must be separated by a url-encoded space (%20). Possible values:none
: [NOT SUPPORTED] no UI will be displayed. If the end-user is already authenticated and consent has been accepted, the redirection to your callback URL is done with a valid code parameter. If the end-user is not authenticated, or consent is needed, the redirection to your callback URL is done with a login_required error. It can be useful to silently check existing authentication or consent.login
: force the connection page display. If the end-user is already authenticated, a page will ask him to confirm the use of his identity to proceed further.consent
: force the consent page display. If the end-user is not already authenticated, the login form is displayed first.
nonce
(optional): String value used to associate a client session with the ID Token. It is passed unmodified from Authorisation request to ID Token. The value should be unique per session to mitigate replay attacks.ui_locales
(optional): [NOT SUPPORTED] End-user's preferred languages and scripts for the user interface, represented as a space-separated list of BCP47 [RFC5646] language tag values. E.g. 'fr en'.id_token_hint
(optional): [NOT SUPPORTED] 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.login_hint
(optional): [NOT SUPPORTED] Hint to the Authorization server about the login identifier the end-user might use to log in (if necessary).acr_values
(optional): [NOT SUPPORTED] 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.
At the end, you need to access the following URL in a Web browser or in a toolkit WebView:
- If using the HTTP GET method, the request parameters are serialized using URI query string serialization. See example, below:
curl --request GET --verbose \
"https://api.orange.com/openidconnect/fr/v1/authorize? \
&response_type=code \
&client_id=6KRHymujF...8SG2g \
&scope=openid \
&state=upToYouData \
&redirect_uri=https%3A%2F%2Fwww.myserver.com%2Foauth2redirect"
- If using the HTTP POST method, the request parameters are serialized using Form serialization. See example below:
curl --request POST --verbose \
--header "Content-Type: application/x-www-form-urlencoded" \
--data "response_type=code \
&client_id=6KRHymujF...8SG2g \
&scope=openid \
&state=upToYouData \
&redirect_uri=https://www.myserver.com/oauth2redirect" \
https://api.orange.com/openidconnect/fr/v1/authorize
Remember that you need to specify the client_id and redirect_uri values you were provided during the registration of your service/client to PAPRICA/OFR OP.
Don't forget to change the state parameter's value (i.e. 'upToYouData'). This opaque value must be generated by your service/client (for each transaction) and 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.
Note the special encoding for redirect_uri value : it must be URL encoded (e.g. "://" has to be replaced by "%3A%2F%2F")
a/ If the transaction succeeds
If the Authorization request is valid, PAPRICA/OFR OP will attempt to authenticate the Orange France end-user.
The end-user (if not already authenticated) will have to authenticate towards the PAPRICA/OFR OP's login form using for its credentials (i.e. login/password).
Once the end-user is authenticated, the PAPRICA/OFR OP must obtain an authorization decision before releasing an authorization code to your service/client. An interactive dialogue with the end-user may be initiated, making it clear what is being consented to.
On success, the redirect URL is automatically called back by PAPRICA/OFR OP with an authorization_code
that is valid during few minutes only:
HTTP/1.1 302 Found
Location: https://www.myserver.com/oauth2redirect?code=OFR-fd19fa859e133481234dd6b2f26ed0dc6d/../9bc9d04bdc81096b644dd5&state=123456789
You can now exchange the obtained code
to get OAuth 2.0 tokens (i.e. ID token, access_token, (refresh_token)). Please note that the 'state' parameter must be used to link the 'authorization code' received through the callback URL to the request your service/client issued.
NOTE: PAPRICA/OFR OP allows the end-user, after authentication, to manage the consents given to applications.
resources - User consent management page: https://openid.orange.fr/oidc/permissions
b/ If the transaction failed
If the Authorization request is not valid (e.g. unknown client_id, invalid redirect_uri), an error page will be returned to the end-user by the PAPRICA/OFR OP.
If the end-user authentication fails or if the end-user does not give its consent, the redirect URL is automatically called back by PAPRICA/OFR OP with a Location header that is set with error details (error code, error description) and state (identical as the state value added in the request).
For example, if the end-user refuses to give its consent, your service/client will receive an error with JSON data similar to:
HTTP/1.1 302 Found
Location: https://www.myserver.com/oauth2redirect?error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+consent&state=upToYouData
See List of errors for further details.
2/ Exchange authorization code against OAuth tokens
From now, your service/client can exchange the obtained "authorization code" for an access_token
, and an id_token
(if the 'openid' scope value was requested by your service/client only).
your service/client must authenticate towards the PAPRICA/OFR OP by communicating the client_id/client_secret credentials in the HTTP Authorization header using the HTTP Basic method ("Authorization" Header = keyword "Basic", followed by a space and the base64 encoding of the concatenation of your client_id, ":" and your client_secret):
The access_token
is mandatory for API calls to protected resources. Additional tokens may be issued by PAPRICA/OFR OP if requested using suitable scope. To get these tokens, a POST request must be sent to the PAPRICA/OFR OP's Token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format:
authorization_header
(required): the credentials of your service/client (i.e. client_id/client_secret).grant_type
(required): the authorization grant type. Fixed: authorization_code.code
(required): the authorization code you received in the callback request (i.e.code
query-string parameter) after calling the Authorization endpoint.redirect_uri
(required): the same callback URL you provided for the Authorization request. Note that it is mandatory for security reasons.
curl --request POST --verbose \
--header "Authorization: {authorization_header}" \
--data "grant_type=authorization_code&code={authorization_code}&redirect_uri={redirect_uri}" \
https://api.orange.com/openidconnect/fr/v1/token
NOTE: In the body part of the request, be sure to use the
authorization_code
you have just received. Do not forget to provide theredirect_uri
also.
As an example:
curl --request POST --verbose \
--header "Authorization: Basic NktSSHl...UdnlrT2lOaA==" \
--data "grant_type=authorization_code \
&code=OFR-fd19fa859e133481234dd6b2f26ed0dc6d/../9bc9d04bdc81096b644dd5 \
&redirect_uri=https%3A%2F%2Fwww.myserver.com%2F/oauth2redirect" \
https://api.orange.com/openidconnect/fr/v1/token
a/ If the transaction succeeds
On success, the HTTP response status will be set to 200 OK, and the body will be a JSON object containing the following fields:
token_type
(required): the token type. Fixed: Bearer.access_token
(required): the access token to be used to retrieve end-user's claims, by setting the header as follows: Authorization: Bearer {access_token}.expires_in
(required): the token validity in seconds. It is the expiration time of the access token in seconds from the time of generation of the response (for example, 3600 seconds).id_token
(optional): the ID token to be used for Identity federation purpose. It is generated only if requested through the 'openid' scope and authorized for your service/client.
At the end, you should receive JSON data similar to:
{
"token_type": "Bearer",
"access_token": "OFR_xjqeEI0bU8rXrfXkvSbPwtQ9WiTOt2LD_75c88e7821be6cc3fa31329453f43a0/../56a5feb8691b6ba66648e47bcba85a908b",
"expires_in": 3600,
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL29wZW5pZC5vcmFuZ2UuZnIiLCJzdWIi/../JEIl0sImF1dGhfdGltZSI6MTYzNTUwMjIxOH0.k37NxnVJ6Z-DjB3sXM50Jbjzq3elCWt9-8BQapXcKUI"
}
From now, you can use this id_token
for identity federation. As defined by OIDC Core 1.0 specification (section 2.), the ID Token is a signed JSON Web Token (JWT) that contains claims about the end-user.
Among these claims, the sub
claim provides an identifier (GID or ISE2) that is persistent and unique for the current end-user of your service/client. You can use it, jointly with the issuer ('iss' claim), in order to store some user-related information (on your server or on the user mobile for example). Next time, the same end-user will authenticate, the same Authorization request will provide you service the same 'sub' value, allowing your service/client to point out to end-user's service data.
TIPS: don't also forget that this ID token must be validated (see ID Token validation section for further details).
b/ If the transaction fails
For example, if you service provide an invalid or expired authorization code, the PAPRICA/OFR OP will return an error message with HTTP 400 (Bad request) status code. As an example:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_grant",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client"
}
See List of errors for further details.
Tokens life-cycle / Refresh tokens
1/ Tokens life-cycle
Access tokens have a limited validity period, they must be renewed periodically (see "expires_in" field ? validity period in seconds). At the present time, the access_token has a lifetime of 1 hour.
To get new tokens you need to complete the two same steps again:
- Send the Authentication/Authorization request to PAPRICA/OFR Authorization server
- Get the tokens
Another mechanism allows you to renew the access tokens based on a refresh_token
without involving the end-user. If one of the requested scope values is authorized and configured to support the delivery of refresh tokens at least, a refresh token will be sent back in the Token response:
As an example:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store Pragma: no-cache
{
"token_type": "Bearer",
"access_token": "OFR_xjqeEI0bU8rXrfXkvSbPwtQ9WiTOt2LD_75c88e7821be6cc3fa31329453f43a0/../56a5feb8691b6ba66648e47bcba85a908b",
"expires_in": 3600,
"refresh_token": "OFR-ce289cd9eab533b074122a482ee221bbc...f6c9956e72ee700f805576585c536e2",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL29wZW5pZC5vcmFuZ2UuZnIiLCJzdWIi/../JEIl0sImF1dGhfdGltZSI6MTYzNTUwMjIxOH0.k37NxnVJ6Z-DjB3sXM50Jbjzq3elCWt9-8BQapXcKUI"
}
At the present time, the refresh token has a lifetime of 1 year.
2/ Using the Refresh token
As stated above, the obtained refresh_token
can be used to get a new access_token
to invoke APIs on the same initially authorized scopes.
Your service/client must authenticate towards the PAPRICA/OFR OP by communicating the client_id/client_secret credentials in the HTTP Authorization header using the HTTP Basic method ("Authorization" Header = keyword "Basic", followed by a space and the base64 encoding of the concatenation of your client_id, ":" and your client_secret):
curl -X POST \
-H "Authorization: Basic NktSSHl...UdnlrT2lOaA==" \
-d "grant_type=refresh_token \
&refresh_token=OFR-ce289cd9eab533b074122a482ee221bbc...f6c9956e72ee700f805576585c536e2 \
&redirect_uri=http%3A%2F%2Fwww.myserver.com" \
https://api.orange.com/openidconnect/fr/v1/token
On success, you will obtain the following response, along with a new access_token
which will allow you to access the end-user's resources:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store Pragma: no-cache
{
"access_token": "OFR_6KRHymujF...8SG2g_cdda38bba6b8eb3860bbd96af2509...9279cec2b91ced71f84",
"token_type":"Bearer",
"expires_in": 3600
}
ID token validation
1/ ID token validation process
The id_token
is a security token that contains claims about the authentication of an end-user towards PAPRICA/OFR OP when using your service/client. This token is represented as a JSON Web Signature (JWS).
Your service/client must validate the ID token in the Token response. As an example (using jwt.io tool):
There are basically three steps to it:
- Check the ID token’s crypto algorithm (i.e. RS256);
- Validate the ID token signature;
- Validate the ID token claims:
- issuer (iss) — does the token originate from the expected Identity provider?
- audience (aud) — is the token intended for my service?
- timestamp (exp) — is the token within its validity window?
For step 1, the ID token is secured with RS256 algorithm. A public key (JSON Web Key [JWK] format) is needed to perform the validation of the ID Token. See section 2/ for further details.
For step 2, your service/client can split the ID Token at the period (".") characters, take the second segment, and base64url decode it to obtain a JSON object containing the list of claims. The
sub
field contains the identifier of the authenticated Orange France end-user.
2/ Retrieve JWKS JSON document
To retrieve the JWKS JSON document, a GET request must be sent to the PAPRICA/OFR OP's JWKS endpoint.
curl --request GET \
https://api.orange.com/openidconnect/fr/v1/jwks
On success, the HTTP response status will be set to 200 OK, and the body will be a JSON object containing the following fields:
keys
(required): an array of JSON Web Key (JWK). Each key entry is a JSON object that represents a public cryptographic key. The members of the object represent properties of the key, including its value.
At the end, you should receive JSON data (with RS256 public key) similar to:
{
"keys": [{
"kty": "RSA",
"kid": "eGq63W62fLOEqRwXr5SQatMkVZ65LV4AUVf1_mzQrMM",
"n": "r_wfT0MCZ9ou9JEjaxRQZApnMtgbbeZq73gtj5QeYs-_UcvO549E7XKRw2xMy7NAdzSTqLED_kzUrPsYpoX_MSLOIGt124JKhPBk2qOYgexQBm4qg_MkiMrDtCw3fEsrQvUds_-kwuQiZGaQO5xpwDzNILwl9GOU-c3FtAXIJMIu-vTNh9x9P7Y-9d1EPL_FfzI413Rdah_HkFUyXimtF3jpPjdrdCZ5Mw_hdOeojJ-Hv9FuwDYhOOpyL_8WwRZzQMNh8V1E5jONEl76NZ4SWWYvbalDw2StUU9NEveRlXJfKYzml4KQUgsW8wPNhquPG1Nf6dWExnp8CPs25e0Lc7ticWtGuGxLTrVaV09fxfrBHr4EC27eZ-EXahhsseloseDs9sUBiZLVOVa82Fs24lyklZynaz1dA7NEM9kduOWKq5UAZygcXBYVLMWw4cQUMCbCRIHQSvSAqV8Dk1hBxuMsHkP1C7aXqN6pUmaKQ2nO7TNNNrVDotb64bWSR96Nhu2ZKg5Ez1gn2UiT_6n4Zbo61CMYN6vBFIXFoVoByYH7VL6_VUIzOUx2BFmI1IzwaKfFfv2SDTAchNdMaFmsAX0Z63wYla04_GU00DITnP_zkA8vbbyRdXiQycAlPEzgyiH0TAUEyru3NcPXHyJUASNEMdP0X43FZJsESf6apSs",
"e": "AQAB"
}]
}
TIPS: The "kid" (key ID) parameter is used to match a specific RS256 public key. This is used, for instance, to choose among a set of keys within a JWK Set during key rollover, or when validating an ID Token issued by the PAPRICA/OFR OP.
Get authorizations for accessing protected API resources
1/ Retrieve user claims using the access token
In order to call PAPRICA/OFR OP's Userinfo API, the access_token
is mandatory. The bearer token must be provided in the request using the HTTP Authorization header.
As an example:
curl --request GET --verbose \
--header "Authorization: Bearer OFR_xjqeEI0bU8rXrfXkvSbPwtQ9WiTOt2LD_75c88e7821be6cc3fa31329453f43a0/../56a5feb8691b6ba66648e47bcba85a908b" \
https://api.orange.com/openidconnect/fr/v1/userinfo
NOTE : Due to the possibility of token substitution attacks, the UserInfo response is not guaranteed to be about the end-user identified by the 'sub' (subject) element of the ID Token. We strongly recommend the 'sub' claim in the UserInfo response to be verified to exactly match the 'sub' claim in the ID Token; if they do not match, the UserInfo response values must not be used.
a/ If the transaction succeeds
On success, the HTTP response status will be set to 200 OK, and the body will be a JSON object containing the following fields:
sub
(required): Subject identifier (ISE2 format). A locally unique and never reassigned identifier within the Issuer for the end-user, which is intended to be consumed by the client.
At the end, you should receive JSON data similar to:
{
"sub": "GXPCGV-200-zwgADJW/a8sr3tuZuapfKz69LAYBNKWbFvq57V+Vu2w="
}
b/ If the transaction fails
If your service/client attempts to make a GET /userinfo request without the Authorization HTTP header, the PAPRICA/OFR OP will return an error message with HTTP 400 (Bad Request) status code.
As an example:
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
WWW-Authenticate: Bearer error="invalid_request", error_description="The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token"
If your service/client or attempts to use an expired or revoked access_token
, the PAPRICA/OFR OP will return an error message with HTTP 401 (Unauthorized) status code.
As an example:
HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
WWW-Authenticate: Bearer error="invalid_token", error_description="The access token provided is expired, revoked, malformed, or invalid for other reasons"
See List of errors for further details.
List of errors
When calling the Authorization endpoint
If an error occurs due to a missing or invalid client identifier or if the redirect URL is invalid, PAPRICA/OFR OP displays a HTML page with the 'Erreur dans la requête | La requête comportait une erreur, veuillez réessayer. Détails: Incohérence entre clientId et redirectUri ou responseType, merci de vérifier votre requête.' error message.
In any other error cases, PAPRICA/OFR OP will redirect the end-user back to the provided "redirect_uri" (HTTP 302 redirection) with the following query-string parameters (each parameter value being URL encoded):
error
: The error type:- access_denied: the end-user cancelled the consent form.
- consent_required: the user has never accepted the Terms Of Service, you have to send the request again without prompt=none so the UI sequence is processed.
- invalid_scope: the given scope does not match the known one, or scope value cannot be understood.
- invalid_request: a required parameter is missing in the request, or a parameter value is unknown.
- login_required: the user is not authenticated; you have to send the request again without prompt=none so the UI sequence is processed.
- unsupported_response_type: response_type value is not supported. Fixed value: code.
- server_error: an internal server error occurred and the request can not be fulfilled.
- temporarily_unavailable: the request could not be currently handled.
error_description
: a brief description of the error. Typical example: consent%20denied in the case the end-user did not give their consent to your service/client for the required operations (as set in thescope
query-string parameter).state
: the value you gave in the Authorization request (state parameter).
As an example:
HTTP/1.1 302 Found
Location: {callback_uri}?error=access_denied&error_description=consent%20denied&state={state}
Below the list of possible errors (non exhaustive):
Error | Error description | |
---|---|---|
access_denied | login failed | |
invalid_scope | scope value cannot be understood | |
invalid_request | syntax error | |
invalid_request | invalid prompt value | - |
unsupported_response_type | unsupported response type | |
consent_required | prompt none | |
login_required | The Authorization Server requires End-User authentication | |
server_error | The authorization server encountered an unexpected condition that prevented it from fulfilling the request |
When calling the Token endpoint
Below is a list of errors that your service/client may receive when calling the PAPRICA/OFR OP's Token endpoint.
The following list of errors fully complies with OAuth 2.0 specification. See [OAUTH] for further details.
HTTP Status | Error code | Error cause | |
---|---|---|---|
400 | invalid_request | The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed. | |
400 | invalid_grant | The provided authorization grant (e.g., authorization code, resource owner credentials) is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client | |
400 | unsupported_grant_type | The authorization grant type is not supported by our PAPRICA/OFR OP's authorization server | |
400 | unauthorized_client | The authenticated client is not authorized to use this authorization grant type | |
400 | invalid_scope | The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner | |
401 | invalid_client | Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method) |
As examples:
1/ Missing Authorization header
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Authorization Required"
Content-Type: application/json
{
"error": "invalid_client",
"error_description": "any authentication credential found"
}
2/ Unknown lient identifier (i.e. c **3/ Invalid client password
HTTP/1.1 401 Bad Unauthorized
Content-Type: application/json
{
"error": "invalid_client",
"error_description": "invalid client password"
}
4/ Unauthorized grant_type (e.g. 'password' instead of 'authorization_code'
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_request",
"error_description": "grant_type parameter is not supported"
}
5/ Invalid grant (i.e. authorization code)
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_grant",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client"
}
When calling the Userinfo endpoint
Below is a list of errors that your service/client may receive when calling the PAPRICA/OFR OP's Userinfo endpoint.
The following list of errors fully complies with OAuth 2.0 Bearer Token usage specification. See [OAUTH 2.0 Bearer Token Usage] for further details.
HTTP Status | Error code | Error cause | |
---|---|---|---|
400 | invalid_request | The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed. | |
401 | invalid_token | The access token provided is expired, revoked, malformed, or invalid for other reasons | |
403 | insufficient_scope | The request requires higher privileges than provided by the access token |
As examples:
1/ Missing Authorization header
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
WWW-Authenticate: Bearer error="invalid_request", error_description="The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token"
Bad Request
2/ Invalid access token
HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
WWW-Authenticate: Bearer error="invalid_token", error_description="The access token provided is expired, revoked, malformed, or invalid for other reasons"
Unauthorized