OAuth 2.0 Client Credentials Flow

Prev Next

The OAuth 2.0 client credentials grant flow allows a web service (confidential client) to authenticate using its credentials, rather than impersonating a user, when calling another web service. This grant, specified in RFC 6749 and sometimes referred to as two-legged OAuth, enables access to web-hosted resources using the identity of an application. It is commonly used for server-to-server interactions that run in the background, without immediate user interaction, and is often referred to as daemons or service accounts.
Key Characteristics:

  • Permissions are granted directly to the application by an administrator.

  • The application presents a token to a resource, which enforces that the app has authorization to perform an action, as there is no user involved in the authentication.

This article provides a comprehensive guide on authenticating with the OnespanSign API using the OAuth 2.0 client credentials flow.

Get a token

Once you've obtained the required authorization for your application, you can proceed to obtain access tokens for APIs. To do this, use the client credentials grant by sending a POST request to the /oauth2/token endpoint of the OnepanSign API to retrieve a token.

This command below was tested with curl versions: 7.8.1 and 8.7.1. We do not guarantee the success on all curl versions

curl -H 'Content-Type: application/x-www-form-urlencoded' \
 -u "clientId:clientSecret" \
 https://apps.esignlive.com/oauth2/token \
 -d "grant_type=client_credentials"

Parameter

Condition

Description

Authorization

Required

Client credentials are accepted in the form of Basic Auth pattern or a header parameter as per RFC 6749.

In the request Headers, pass the Base64 encoded string representing your 'client_id' and 'client_secret' values, appended to the text Basic as follows:

``` Basic <Base64 encoded client_id and client_secret> ```
Base64 encoded client_id and client_secret = Base64 of "client_id:client_secret"

grant_type

Required

Must be set to client_credentials. Starting from release 24.R5, 'grant_type' will not be accepted as a query parameter. It will only be accepted as a form data.

sender_id

Optional

ID of the sender. The sender must exist exist and must be part of the same account as the Client ID. Note that this parameter is only available starting with the 25R.4 release.

delegator_id

Optional

ID of the delegator. If enabled, the Sender ID must also be defined, as a delegation must exist between the sender and the delegator. Note that this parameter is only available starting with the 25R.4 release.

Successful response

A successful response looks like this:

{

 "access_token": "eyJraWQiOiIxOTk5OGJhOS1jYTY1LTQ3ODYtOGYzMi01ZGUxZDNhM2JhYTUiL....",

 "token_type": "Bearer",

 "expires_in": 299

}

Parameter

Description

access_token

The requested access token. The app can use this token to authenticate to the secured resource, such as to a web API.

token_type

Indicates the token type value. The only type that the OnespanSign API supports is bearer.

expires_in

The amount of time that an access token is valid (in seconds).

OnespanSign API does not offer token refresh functionality, so a new token must be generated once the existing one expires. This requires additional handling on the application side by integrators using the OnespanSign API. However, the Esl SDK provides automatic token recreation on the client side, simplifying the process.

Use a token

Now that you've acquired a token, use the token to make requests to the resource. When the token expires, repeat the request to the 'oauth2/token' endpoint to acquire a fresh access token.

GET /aws/rest/services/packages HTTP/1.1

Host: apps.esignlive.com

Accept: application/json

Content-Type: application/json

Authorization: Bearer eyJraWQiOiIxOTk5OGJhOS1jYTY1LTQ3ODYtOGYzMi01ZGUxZDNhM2JhYTUiLCJhbGciOiJSUzI....

Token Claims

Standard claims, as defined in RFC 7519, are present in the token (such as issuer, date, etc.). If sender_id and/or delegator_id are provided in the form data, the corresponding sender_id and/or delegator_id claims will also be included in the token.

OAuth2 Implementation

For oAuth2 authentication, the implementer should reuse the generated token until it expires instead of creating a new token on every call.

The SDK handles this properly, by caching the clients created and those clients retain the token, and before every call made by the SDK, the token expiry is verified, and the SDK will decide on whether a new token is needed or not.

When using the SDK, there's nothing to be done by the implementer except following the suggested usage below.

In both cases above the ossClient / eslClient will be cached in memory and the SDKs will enforce that the clients reuse the oAuth2 token and regenerate a new token when it expires. All in the background without the need of any additional implementation.

Java SDK

EslOAuthClientConfig config = EslOAuthClientConfig.Builder()
            .withClientId("clientId") // Mandatory: replace with your clientId
            .withClientSecret("clientSecret") // Mandatory: replace with your clientSecret
            .withSenderId(senderId) //Optional (new R4) replace with the sender id you want to impersonate
            .withDelegatorId(delegatorId) //Optional (new R4) replace with the delgator id that gave permission on sender id to act on his behalf
            .withAuthenticationServer("authenticationServer") // Mandatory: replace with the OneSpan's authorization server url
            .withApiUrl("apiUrl") // Mandatory: replace with OneSpan's API url
            .withAllowAllSSLCertificatesFlag(allowAllSSLCertificatesFlag) // Optional: default false
            .withUseSystemProperties(useSystemProperties) // Optional: default false. If this is set to true then all proxy configurations should be passed as system properties
            .withProxyConfig(proxyConfig) // Optional: default null. To be passed if proxy is required and useSystemProperties is set to false
            .withHeaders(headers) // Optional: default empty map. To be passed if extra headers are need to the request
            .build();
         
        EslClient eslClient = EslOAuthClientProvider.getInstance().getEslClient(config);
         
        //proceed to make calls to our API using eslClient.

.NET SDK

OSSAuthClientConfig config = new OSSAuthClientConfig.Builder()
                .WithClientId(clientId) // Mandatory: replace with your clientId
                .WithClientSecret(clientSecret) // Mandatory: replace with your clientSecret
                .WithAuthenticationServer(authenticationServer)// Mandatory: replace with the OneSpan's authorization server url
                .WithApiUrl(apiUrl) // Mandatory: replace with OneSpan's API url
                .WithAllowAllSSLCertificatesFlag(allowAllSSLCertificatesFlag) // Optional: default false
                .WithUseSystemProperties(useSystemProperties) // Optional: default false. If this is set to true then all proxy configurations should be passed as system properties
                .WithProxyConfiguration(proxyConfig) // Optional: default null. To be passed if proxy is required and useSystemProperties is set to false
                .WithHeaders(headers) // Optional: default empty map. To be passed if extra headers are need to the request
                .Build();
 
            OssClient ossClient = OSSAuthClientProvider.Instance.GetOssClient(config);
          //proceed to make calls to our API using ossClient

API direct call

When the API is accessed without the use of SDKs, then it's on the implementer side to cache in memory the oAuth2 token as follows:

  • cache the token per clientId key pair (key: clientId, value: token)

  • check if the token is expired before every call and give it a few seconds buffer. If the token, with buffer, is expired then call OneSpan's authorization service to get a new token, otherwise re-use the same token.