Skip to main content

Authentication & Authorization

Authentication & Authorization is centralized, based on OpenID Connect standards.

REST APIs, applications and services use centralized OpenID Connect Authentication & Authorization service.

In order to use/consume REST APIs, your client applications and services have to authorize using security tokens retrieved from centralized Authorization Service (or Security Token Service).

Concepts

OpenID Connect and OAuth 2.0 are very similar; in fact, OpenID Connect is an extension on the top of OAuth 2.0.

The two fundamental security concerns, authentication and API access, are combined into a single protocol - often with a single round trip to the security token service.

The combination of OpenID Connect and OAuth 2.0 is the best approach to secure modern applications and services.

THe implementation of these protocols is highly optimized to solve typical security problems of today's mobile, native and web applications.

Applications have two fundamental ways with which they communicate with APIs using the application identity or delegating users identity.

Sometimes both methods need to be combined.

OAuth2 is a protocol that allows applications to request access tokens from a Security Token Service (or Authorization Service) and use them to communicate with APIs.

This delegation reduces complexity in both the client applications and the APIs since authentication and authorization can be centralized.

Terminology

Authorization service is an OpenID Connect provider - it implements the OpenID Connect and OAuth 2.0 protocols.

Different terms can be denoted such as Security Token Service (STS), Identity Provider, Authorization Server, etc.

User

A user is a person who's using a registered client to access resources.

Client

A client is a piece of software that requests tokens from Authorization Service - either for authenticating a user (requesting an identity token) or for accessing a resource (requesting an access token). A client must be first registered with Authorization Service before it can request tokens. Examples for clients are web applications, native mobile or desktop applications, SPAs, server processes, etc.

Resources (REST APIs)

Resources are something you want to protect with Authorization Service - either identity data of your users, or APIs. Every resource has a unique name - and clients use this name to specify to which resources they want to get access. Identity data or Identity information (a.k.a. claims) about a user, e.g. name or email address. APIs are resources that represent functionality a client wants to invoke - typically modelled as Web APIs, but not necessarily.

Identity Token

An identity token represents the outcome of an authentication process. It contains at a bare minimum an identifier for user (called the sub a.k.a. subject claim) and information about how and when user authenticated. It can contain additional identity data.

Access Token

An access token allows access to an API resource. Clients request access tokens and forward them to the API. Access tokens contain information about the client and user (if present). APIs use that information to authorize access to their data.

Grant Types

The OpenID Connect and OAuth 2.0 specifications define so-called grant types (often also called flows - or protocol flows). Grant types specify how a client can interact with the token service.

Your application/service will be assigned one of the grant types by our team, based on your client type. This allows locking down the protocol interactions that are allowed for a given client.

A client can be configured to use more than a single grant type such as Authorization Code Flow for user centric operations or Client Credentials for server to server communication.

In general,

If you're developing a web app/service running on the server, i.e. server to server communication will happen and client secret can be safely stored, then the Client Credentials grant is the recommended choice.

In scenarios where storing the client secret is NOT safe (e.g. desktop, mobile apps or JavaScript web apps running in the browser), Authorization Code with PKCE, as it provides protection against attacks where the authorization code may be intercepted.

Procedure For Obtaining Access to Authorization Service

Your client application and/or service needs to be defined on Authorization Service so that you can obtain required credential information to access APIs. The procedure is as follows:

  1. Complete the business relationships with in order to be eligible to use APIs.
  2. Provide the following to our team:
    • Your application/service name that will use APIs
    • Your application/service type in terms of platforms such as mobile, web, desktop, or server app, etc.
    • Your application/service URIs/IPs that will use APIs
  3. We will define your application on Authorization Service
  4. We will provide you with the following information:
    • clientId: your client application/service will use to identify itself when obtaining security token from Authorization Service
    • clientSecret(s): your client application/service will use to identify itself when obtaining security token from Authorization Service
    • allowed grant type(s): your client application/service can have
    • allowed scope(s): you client application/service can use

Client Credentials Flow (server to server communication)

If you're developing a web app/service running on the server, i.e. server to server communication will happen and client secret can be safely stored, then the Client Credentials grant is the recommended choice.

Authorization Service discovery endpoint is defined on https://id-test.koala.markets/.well-known/openid-configuration

  1. Your application/service (client of Authorization Service) requests access_token using client_id, client_secret, scope which will be provided by our team.

  2. The Authorization Service will provide the access code that your application/service can use to call APIs in a server to server scenario.

  3. Your application/service (client of Authorization Service) calls the API using obtained access token from previous step.

In github, there is an example of this Client Credentials flow.

Please check Java OAuth2 Server Client Example

1. Request Access Token via client_credentials

You can request an access token via a single call to Authorization Service token url

with the following

clientId (our team will provider it)

clientSecret (our team will provider it)

scope (our team will provider it)

grant_type should be "client_credentials"

2. Use Access Token To Call REST APIs

The access token allows you to make requests to the REST API. To do so, you need to include the following header in your API calls:

HEADER PARAMETERRequiredVALUE
AuthorizationRequiredValid access token following the format: Bearer <Access Token>

The following example uses cURL to get open trade orders of your client with id:

curl --request GET \
'https://order-management-test.koala.markets/api/client/{clientId}/order?pageNumber=1&recordsPerPage=20' \
--header "Authorization: Bearer kdRTwx...ugD"

Authorization Code Flow with PKCE (web/mobile/desktop apps reaching with users)

In scenarios where storing the client secret is NOT safe (e.g. desktop, mobile apps or JavaScript web apps running in the browser), Authorization Code with PKCE, as it provides protection against attacks where the authorization code may be intercepted.

Authorization Service discovery endpoint is defined on https://id-test.koala.markets/.well-known/openid-configuration

  1. Your application/service (client of Authorization Service) requests user authorization login

  2. The Authorization Service will provide the authorization code that your application/service can use to obtain access token.

  3. Your application/service (client of Authorization Service) requests access token using the authorization code obtained in previous step.

  4. Your application/service (client of Authorization Service) calls the API using obtained access token from previous step.

1. Request User Authorization Code

The first step is to request authorization from user, so our app can access to REST APIs in behalf of that user. To do so, our application must build and send a GET request to the https://id-test.koala.markets/connect/authorize endpoint with the following parameters:

QUERY PARAMETERRequiredVALUE
client_idRequiredThe Client ID generated after registering your application.
response_typeRequiredSet to "code"
redirect_uriRequiredThe URI to redirect to after user grants or denies permission. This URI needs to have been entered in the Redirect URI allowlist that you specified when you register your application (See the app settings guide). The value of redirect_uri here must exactly match one of the values you've entered when you register your application including upper or lowercase, terminating slashes and such.
stateOptional but strongly recommendedThis provides protection against attacks such as cross-site request forgery. See RFC-6749.
scopeOptional but strongly recommendedA space-separated list of scopes. Such as "scope=openid profile email phone"
code_challenge_methodRequiredSet to "S256"
code_challengeRequiredSet to the code challenge that your app calculated in step 1

In order to generate the code_challenge, your app should hash the code verifier using the SHA256 algorithm. The code verifier is a random string between 43 and 128 characters in length. It can contain letters, digits, underscores, periods, hyphens, or tildes.

Example

The following JavaScript code example implements the /login method using Express framework to initiates the authorization request:

var client_id = 'YOUR_APP_CLIENT_ID';
var redirect_uri = 'https://your-app.domain.com/callback';

var app = express();

app.get('/login', function(req, res) {

var state = generateRandomString(16);
var scope = 'openid profile email phone';

res.redirect('https://id-test.koala.markets/connect/authorize?' +
querystring.stringify({
response_type: 'code',
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state
}));
});

Once the request is processed, user will see the authorization dialog asking to authorize access within the scopes openid profile email phone.

The Authorization Service presents details of the scopes for which access is being sought. If user is not logged in, they're prompted to do so using their credentials. When user is logged in, they're asked to authorize access to the data sets or features defined in the scopes.

Finally, user is redirected back to your specified redirect_uri. After user accepts or denies your request, the Authorization Service OAuth 2.0 protocol redirects user back to your redirect_uri. In this example, the redirect address is https://your-app.domain.com/callback

Response If user accepts your request, then user is redirected back to the application using the redirect_uri passed on the authorized request described above.

The callback contains two query parameters:

QUERY PARAMETERVALUE
codeAn authorization code that can be exchanged for an Access Token.
stateThe value of the state parameter supplied in the request.

For example:

https://your-app.domain.com/callback?code=hlreAF...qw&state=12GThgs765

If user does not accept your request or if an error has occurred, the response query string contains error information.

2. Request Access Token

If user accepted your request, then your app is ready to exchange the authorization code for an Access Token. It can do this by making a POST request to the https://id-test.koala.markets/connect/token endpoint.

The body of this POST request must contain the following parameters encoded in application/x-www-form-urlencoded:

REQUEST BODY PARAMETERRequiredVALUE
grant_typeRequiredThis field must contain the value "authorization_code".
codeRequiredThe authorization code returned from the previous request.
redirect_uriRequiredThis parameter is used for validation only (there's no actual redirection). The value of this parameter must exactly match the value of redirect_uri supplied when requesting the authorization code.

If you're implementing the PKCE extension, these additional parameters must be included as well:

REQUEST BODY PARAMETERRequiredVALUE
client_idRequiredThe client ID for your app, available from the developer dashboard.
code_verifierRequiredThe value of this parameter must match the value of the code_verifier that your app has generated in the previous step.

The request must include the following HTTP headers:

HEADER PARAMETERRequiredVALUE
AuthorizationRequiredBase 64 encoded string that contains the client ID and client secret key. The field must have the format: Authorization: Basic <base64 encoded client_id:client_secret>
Content-TypeRequiredSet to application/x-www-form-urlencoded.

Response On success, the response will have a 200 OK status and the following JSON data in the response body:

KEYVALUE TYPEVALUE DESCRIPTION
access_tokenstringAn Access Token that can be provided in subsequent calls, for example to REST API services.
token_typestringHow the Access Token may be used: always Bearer.
scopestringA space-separated list of scopes which have been granted for this access_token
expires_inintThe time period (in seconds) for which the Access Token is valid.
refresh_tokenstringA token that can be sent to Accounts service in place of an authorization code. (When the access code expires, send a POST request to the Accounts service connect/token endpoint, but use this code in place of an authorization code. A new Access Token will be returned. A new refresh token might be returned too.)

The following example, shows how the successful response looks like:

{
"access_token": "..kdRTwx...",
"token_type": "Bearer",
"scope": "openid profile email phone",
"expires_in": 3600,
"refresh_token": "..udfAGf..."
}

3. Use Access Token To Call REST APIs

The access token allows you to make requests to the REST API. To do so, you need to include the following header in your API calls:

HEADER PARAMETERRequiredVALUE
AuthorizationRequiredValid access token following the format: Bearer <Access Token>

The following example uses cURL to get open trade orders of your client with id:

curl --request GET \
'https://order-management-test.koala.markets/api/client/{clientId}/order?pageNumber=1&recordsPerPage=20' \
--header "Authorization: Bearer kdRTwx...ugD"