This type of authentication is only available to select partners upon request.
This authentication flow is suitable for server-to-server integrations where authentication needs to be done without human intervention.
Your OpenAPI Application
When an application is created for you on OpenAPI, you will receive the following application details:
Name | Description | Example |
---|---|---|
AppUrl | A URL uniquely representing your app. | http://localhost/mytestapp |
AuthenticationUrl | The URL of the Saxo Bank authentication & authorization server. | https://sim.logonvalidation.net/ |
AppKey | The Application key identifying your application. | 1234-5678-9101 |
AppSecret | The Application "secret" identifying your application. | abcdefghijklmn |
OpenApiBaseUrl | Base URL for calling OpenAPI REST endpoints. | https://gateway.saxobank.com/sim/openapi/ |
These can be mapped to the necessary OAuth parameters:
OAuth Parameter | Saxo App Value | Example |
---|---|---|
client_id | AppKey | 1234-5678-9101 |
client_secret | AppSecret | abcdefghijklmn |
token_url | AuthenticationUrl + '/token' | https://sim.logonvalidation.net/token |
Below parameters are static: | ||
grant_type | Must be 'urn:saxobank:oauth:grant-type:personal-jwt' | urn:saxobank:oauth:grant-type:personal-jwt |
Obtaining a Certificate
After having received your application, you need to obtain a certificate, please follow the steps described here to get it: Managing Certificates in MyAccount
Creating the JSON Web Token
For an introduction to JWTs, see this Introduction to JSON Web Tokens
We require the JWT to be created with the following header and claims:
Header | Description | Standard | Sample Value |
---|---|---|---|
x5t | Thumbprint of X509 certificate used for signing JWT. Cert downloaded from MyAccount. | RFC 7515 | 935093f1690900asdfd98626dfw35fa22b41d9dfd |
alg | Algorithm used to sign JWT. We only support RS256 at the moment. | RFC 7518 | RS256 |
Claim | Description | Sample Value |
---|---|---|
iss | Issuer - Value should be AppKey of client application. | 031dc97fb7f340b0a78199785c771021 |
sub | UserId - Value should be the user id for which token is needed. | 12345 |
exp | Expiry - Value should be a unix time stamp indicating expiry of the token. | 1514456107 |
aud | Audience - Value should be the AuthenticationUrl | https://sim.logonvalidation.net/token |
spurl | AppUrl - The AppUrl of your application. | http://localhost/mytestapp |
Requesting the Access Token
Once the JWT has been created and signed, it can be exchanged for an access token by sending a POST request to the token_url. This request needs to be authenticated using HTTP Basic Auth with your client_id as username and client_secret as password. The basic auth should be a base64 encoded string in the following format: "client_id:client_secret". The JWT is sent in a parameter named 'assertion'
POST /token HTTP/1.1 Host: sim.logonvalidation.net Authorization: Basic MTIzNC01Njc4LTkxMDE6YWJjZGVmZ2hpamtsbW4= Content-Type: application/x-www-form-urlencoded grant_type=urn%3Asaxobank%3Aoauth%3Agrant-type%3Apersonal-jwt &assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.eyJpc3Mi[...omitted for brevity...]
If your OAuth library does not support sending the credentials as HTTP Basic Auth, we also accept them as part of the post body:
POST /token HTTP/1.1 Host: sim.logonvalidation.net Content-Type: application/x-www-form-urlencoded grant_type=urn%3Asaxobank%3Aoauth%3Agrant-type%3Apersonal-jwt &assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.eyJpc3Mi[...omitted for brevity...] &client_id=1234-5678-9101 &client_secret=abcdefghijklmn
The response to this request will contain an access_token and a refresh_token:
{ "access_token" : "eyJhbGc.eyJvYWEiOiIwMDA0NCIsImlzcQ.gElDA_9M0_eDr6Jw[...omitted for brevity...]", "expires_in": 1200, "token_type": "Bearer", "refresh_token": "5e7fa3d2-5e13-4736-80c1-9c3e5cde660b", "refresh_token_expires_in": 2400 }
Using the Refresh Token
If you were provided with a refresh token you can use it to keep the connection alive by exchanging it for a new access and refresh token within it's lifetime.
To do this, send another request to the /token endpoint with 'grant_type=refresh_token':
POST /token HTTP/1.1 Host: sim.logonvalidation.net Authorization: Basic MTIzNC01Njc4LTkxMDE6YWJjZGVmZ2hpamtsbW4= Content-Type: application/x-www-form-urlencoded grant_type=refresh_token &refresh_token=5e7fa3d2-5e13-4736-80c1-9c3e5cde660b
See the code sample in NodeJs for CBA.