2-Legged OAuth flow step by step
Published: August 7, 2024
Before starting
API URL endpoints
application-only Authentication
Access protected resources using OAuth access token
Misuse of access token
List of errors
Sample code
Before starting
In order to call our APIs, you will need credentials for your client application: they are used by the back-end platform to identify your client application and allow it to make calls to the APIs. You receive these credentials when you register your client application on the Orange Developer portal.
At the end of the registration process, you are provided with:
- a
client_id
: a unique ID provided by the Orange back-end server to identify your client application, - a
client_secret
: is a secret known only to the application and the authorization server. It is used to authenticate your client application,
The client_id
and client_secret
are used in the ‘Basic’ HTTP Authentication scheme (RFC 7617) to compute the value of the Authorization
HTTP header.
Its value is composed of the keyword “Basic”, followed by a space and the base64 encoding of the concatenation of your client_id
, “:” and your client_secret
.
In Javascript, the authorization_header
will look something like:
authorization_header = Basic + btoa(client_id + ":" + client_secret)
Our developer dashboard provides directly this information.
WARNING: OAuth 2.0 authorization protocol requires the use of HTTPS for communications between the client and Orange Authorization Server due to the exchange of sensitive data (for instance, app’s credentials – i.e. client_id, client_secret, access token).
API URL endpoints
On ORANGE DEVELOPER, API access are protected using OAuth 2.0 protocols: when requesting an API on its consumption URL endpoint, you’ll need to present a valid OAuth 2.0 access token.
On ORANGE DEVELOPER, these tokens are to be negotiated on a specific /oauth
resource path (see below) on the same URL (FQDN) of the API you want to access.
WARNING: in the following paragraphs, you’ll find some real-life curl requests, highlighting examples of OAuth 2.0 token negotiation for APIs published on the api.orange.com FQDN.
DO NOT TAKE THESE EXAMPLES FOR GRANTED AS YOUR PARTICULAR API MAY BE PUBLISHED ON A DIFFERENT FQDN
RATHER, CHECK YOUR SPECIFIC API OFFER DOCUMENTATION SECTION TO LOOK FOR THE PROPER FQDN TO BE USED IN YOUR CASE.
Below is the list of possible API URL FQDNs on ORANGE DEVELOPER.
TLS | FQDN | Usage | |
---|---|---|---|
1-way | https://api.orange.com OBS(*): https://ope-obs.apibackbone.orange.com |
Default access | |
2-way | https://api-ma.orange.com OBS(*): https://ope-obs-ma.apibackbone.orange.com |
Available on some APIs that offer mutual authentication |
(*): specific FQDNs for some APIs provided by Orange Business Services (OBS)
application-only Authentication (aka 2-Legged OAuth)
Orange offers client applications the ability to issue authenticated requests to our API on behalf of the client application itself (as opposed to on behalf of a specific end-user). Orange Authorization server’s implementation is based on the Client Credentials Grant flow of the OAuth 2.0 specification.
The client_credentials
grant type is used when a client application needs to get an access token for its own account (using client_id/client_secret credentials), outside the context of any specific user.
Discovery mechanism
The discovery endpoint /oauth/v3/.well-known/oauth-authorization-server
provides all necessary information your application will need to manage access_token
(token endpoint, supported authentication methods for token endpoint, etc.).
Example on the api.orange.com FQDN :
GET https://api.orange.com/oauth/v3/.well-known/oauth-authorization-server HTTP/1.1
Host: api.orange.com
{
"issuer": "https://api.orange.com/oauth/v3",
"jwks_uri": "https://api.orange.com/oauth/v3/jwks",
"token_endpoint": "https://api.orange.com/oauth/v3/token",
"grant_types_supported": ["client_credentials"],
"token_endpoint_auth_methods_supported": ["client_secret_post","client_secret_basic"],
"token_endpoint_auth_signing_alg_values_supported": ["RS256","ES384"],
"introspection_endpoint": "https://api.orange.com/oauth/v3/introspect",
"introspection_endpoint_auth_methods_supported":["client_secret_post","client_secret_basic"],
"introspection_endpoint_auth_signing_alg_values_supported": ["RS256","ES384"]
}
Get OAuth access token
WARNING: Token requests are limited to 50 requests per minute, when the rate limit is exceeded you will receive a 429 error.
WARNING: Header
Accept: application/json
is now required, when it’s omitted you will receive an error 406 error.WARNING: Header
Authorization
is now forbidden when providing client_id/client_secret in the body, you will receive an error 400 error Duplicate credentials.
The access_token
is mandatory for API calls to protected resources. To get this token, a POST request must be sent to the token endpoint by adding the following parameters using the “application/x-www-form-urlencoded” format:
Authorization
(Header) (required): the credentials of your client application (i.e. client_id/client_secret). See Before starting section.Accept
(Header) (required): the response media types that is/are acceptable by the client. For this token negotiation,Accept
header MUST be valued with at least one of the following media type declaration :application/json
or*/*
.grant_type
(required): the authorization grant type. Fixed: client_credentials.
curl -X POST \
-H "Authorization: {authorization_header}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "grant_type=client_credentials" \
https://api.orange.com/oauth/v3/token
As an example:
curl -X POST \
-H "Authorization: Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "grant_type=client_credentials" \
https://api.orange.com/oauth/v3/token
Please note that, when you perform POST requests with curl or wget, parameters are specified as
application/x-www-form-urlencoded
through the use of the -d flag.
a/ If the transaction succeeds
The authorization server issues an access_token
and constructs the response by adding the following parameters to the entity-body of the HTTP response with a 200 (OK) status code:
token_type
(required): the type of the token issued. Fixed: Bearer.access_token
(required): the access token issued by the authorization server, and to be used for your API calls, by setting the header as follows: Authorization: Bearer {access_token}.expires_in
(required): the lifetime in seconds of the access token.
At the end, you should receive JSON payload similar to:
HTTP/1.1 200 OK
Content-Type: application/json
{
"token_type": "Bearer",
"access_token": "eyJ2ZXIiOiIxLjAiLCJ0eXAiOiJKV1Q.....ODSHIjf",
"expires_in": 3600
}
From now, you can use this access_token
for all subsequent API calls to protected resources (see Access protected resources using OAuth access token section for more information).
NOTE: The
access_token
is valid for the duration, in seconds, specified byexpires_in
. Therefore, you do not need to request a new access token as your client application doesn’t receive an error indicating that your access token expired.If no other value is specified in the getting started page of the API offer,
access_token
default lifetime is 60 minutes (3600 seconds).
b/ If the transaction fails
Because you provide invalid credentials for example, you will get an error with JSON payload similar to:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate : Basic realm="Authorization Required"
{
"error": "invalid_client",
"error_description": "The requested service needs credentials, but the ones provided were invalid."
}
See List of errors for further details.
Access protected resources using OAuth access token
In order to call our API, the access_token
is mandatory. The bearer token must be provided in the request using HTTP Authorization header.
curl -X GET \
-H "Authorization: Bearer {access token}" \
https://api.orange.com/{api}/vM/{resource}
As an example:
curl -X GET \
-H "Authorization: Bearer eyJ2ZXIiOiIxLjAiLCJ0eXAiOiJKV1Q.....ODSHIjf" \
https://api.orange.com/poi/v1/shops?postalCode=35000
If your client application attempts to use an expired or revoked access_token
, an invalid token error will be returned.
There are some cases where your client application will no longer gain access to API resources, and get an error back.
Please check the following points:
- You attempt to use an expired or revoked
access_token
and you get an invalid token error. You will have to request a newaccess_token
(as explained in Get OAuth access token). As an example:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate : Basic realm="Authorization Required"
{
"code": 42,
"message": "Expired credentials",
"description": "The requested service needs credentials, and the ones provided were out-of-date."
}
- You removed your subscription to the API so that the capability to generate an
access_token
is not allowed anymore. As an example:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"code": 50,
"message": "Access Denied",
"description": "The application that makes the request is not authorized to access this endpoint (ex: not a subscribed service)."
}
- ORANGE DEVELOPER managers have suspended your access (as a consequence of the non-fulfilment of conditions of use for example).
Misuse of access token
Please be aware that a great number of calls for token could have side effects and impact other developers.
We may use protection mechanisms such as limiting token requests. Unfortunately in exceptional cases we can also block your API usage (your application, your account or even your IP) for security reasons.
Please adjust your client application code to use access tokens correctly. One token is valid 1 hour so there is no need to make more token requests to use our products. Mostly do not generate a new token for every functional call.
If you get errors, follow the error description available in the response
List of errors
Below a list of errors (non exhaustive) that your client application can get when calling the token endpoint of the Orange Authorization Server .
The following list of errors fully comply with OAuth 2.0 specification.
HTTP Status | Error (mandatory) | Error description (optional) | Possible fixes | |
---|---|---|---|---|
400 | invalid_grant | The parameter grant_type is not valid. | Check that the ‘grant_type’ parameter is well set with ‘client_credentials’ value | |
400 | invalid_request | The URI does not support the requested method. | Check that you use the right HTTP method (GET, POST, PUT…) | |
400 | invalid_request | The requested URI or the requested resource does not exist. | Check if URI and endpoint are valid | |
400 | invalid_request | Duplicate credentials. | Provide only one credential, Authorization in header OR client_id /client_secret in body |
|
400 | invalid_request | Missing grant_type parameter. | Check that the ‘grant_type’ parameter is present | |
400 | unauthorized_client | The requested service needs credentials, but the ones provided were not approved. | Check that the status of your subscription to the API offer (must be ‘Approved’) | |
401 | invalid_request | The received request is invalid. | Check that your request is well formed (e.g. no duplicate headers – e.g. Authorization) | |
401 | invalid_client | The requested service needs credentials, but the ones provided were invalid. | Check if Authorization request header is set with the right Bearer token. E.g. Authorization: Bearer VOZG7/..//aJPA | |
401 | invalid_client | The requested service needs credentials, but the ones provided were invalid. | Check if Authorization request header is set with the right Bearer token. E.g. Authorization: Bearer VOZG7/..//aJPA | |
401 | invalid_client | Unable to decode Basic authorization. | Check that authorization header is base64 encoded as explained in Introduction | |
401 | invalid_client | Client certificate fingerprint is not matching with those registered for your application. | Check that you use the right client certificate. | |
403 | invalid_request | TLS 2 ways endpoint (i.e https://api-ma.orange.com/) is not valid for your application. | Make your token request to https://api-ma.orange.com/oauth/v3/token instead of https://api.orange.com/oauth/v3/token | |
403 | invalid_client | Access denied for client. | The @IP of your client is not authorized | |
404 | not_found | The requested URI does not exist. | Check that the target endpoint exist | |
405 | method_not_allowed | The URI does not support the requested method. Please check API documentation. | POST HTTP method is required for your Token request | |
406 | invalid_request | Application must accept application/json response. | Check that your request include Accept: application/json in the header |
|
413 | invalid_request | Request-Body too long. | Check the size of the payload in the body | |
414 | invalid_request | Request-URI too long. | Check the length of your URL | |
415 | invalid_request | Unsupported media type, Content-Type header must be application/x-www-form-urlencoded. | Check that your request include Content-Type: application/x-www-form-urlencoded in the header |
|
429 | too_many_requests | The application has made too many calls and has exceeded the rate limit for this service. | Retry your API call after a short delay (in seconds) | |
500 | server_error | is not supported. | Bad configuration for your client. Please contact us to fix this behaviour | |
503 | server_error | The service is temporarily unavailable. | Our service is temporarily down, contact support if problem persist | |
4xx/5xx | any | Error not managed yet. | Our service raised an unmanaged error. Please contact us to fix this behaviour |
As an example:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_grant",
"error_description": "The parameter grant_type is not valid."
}
References
- [OAUTH] Hardt, D., “The OAuth 2.0 Authorization Framework” RFC 6749, October 2012.
- [JSON] “Introducing JSON”
Sample code
You could find some sample code available.