API

Authorization

The RamBase API is secured using the OAuth 2.0 standard. Only registered clients can access the API. Depending on the application being built there will be different authentication flows to choose between.

This Oauth 2.0 implementation is based on the Oauth 2.0 specification version 25. The specification can be found here:
http://tools.ietf.org/html/draft-ietf-oauth-v2-25

Since we use a standardized way of securing the API you can connect using standard Oauth 2.0 client libraries. This document describes how to connect if you do not use a client library.

The RamBase API uses two-factor authentication where possible.

1. Overview of the different authorization flows

There are 4 different authorization flows you can choose between. That does not mean that you can pick the one you like the best, but depending on the type of application you are building we will together agree on the appropriate application flow for your application. You can find a quick overview of the different authorization flows below:

Server-side web application flow: This flow is used when the client is a web application server. Client secret and refresh token should never be leaked to the browser (or native client) where the user may have access to it. When a client logs in on the login page provided by RamBase you get an authorization code which needs to be exchanged for an access token. Another name of this flow is Authorization code flow. You can use this flow even if your application is not a server-side web application if the application uses a backend which is a server-side application.

Client-side web application flow: This flow is also called Implicit Grant Flow. It should be used when only temporary access to data is required. The oauth client is running in the browser (using javascript/flash/silverlight). Refresh token’s is not allowed in this flow, but we support sliding expiration of the access token. When you use this flow, you do not get an authorization code and you do not have a client-secret.

Resource owner password flow: When using this flow you are exchanging the username/password with an access token directly. Because the resource owner's password is exposed to the application, this flow should be used sparingly. It is recommended only for first-party "official" applications released by the API provider (JHC), and not open to wider third-party developer communities. Refresh token is not allowed, but we support sliding expiration.

Client Credentials flow: This flow is used when the client is acting on behalf of the app itself. Typically a server login. Client id and client secret is exchanged for an access token. It is extremely critical that the client secret and access token is kept highly confidential. Refresh tokens is not supported. If the access token expires the server will ask for a new access token directly without using a refresh token.

2. Getting access to RamBase API

To be able to access the RamBase API you need to register your application with Hatteland Computer. We will need to know the following about your application.

  • Name of application
  • Who is responsible for the application
  • Type of application (server-side web app/client side web app/mobile app/windows app)

For web applications you need to provide a redirect_uri that your application uses. When the user grants access (or denies) the RamBase authorization server will redirect to this uri.

When you have registered the application with JHC you will be provided a client_id. Depending on the type of application you are developing you will maybe also retrieve a client_secret.

3. Getting an access token

No matter which authorization flow you are using, you need an access token to make any requests to the RamBase API.

3.1. Server-side web application flow

This flow is designed for web applications with servers that can store information and maintain state. While this section walks through the steps your code would go through to use OAuth 2.0 in a server-side web application, you could also use one of several client libraries in your OAuth 2.0 implementation.

API clients might have the The Proof Key for Code Exchange (PKCE, pronounced pixie) extension enabled, which requires some extra data exchange. Even if your API client is not set up to require these extra steps, you can include them to improve the security of your application.

3.1.1. Step 1

When a user first tries to perform an action that requires API authentication, direct the user to RamBase's authorization server at https://api.rambase.net/oauth2. The authorization server will refuse HTTP connections because it is only accessible over SSL (HTTPS). It supports the following URL parameters:

client_id Required The OAuth 2.0 client ID for your application. The RamBase administrators will give you this when you register your application as a client
redirect_uri Required A registered redirect_uri for that client ID.
response_type Required Set this parameter's value to code.
state Optional Any string that your application would use to maintain state between the request and redirect response. Your application will receive the same value that it sends for this parameter. For example, you could use this parameter to redirect the user to a particular resource in your application
code_challenge Required* To create a code_challenge you first need to create a code_verifier. You will need this code_verifier again in step 4. The code_verifier is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.

The code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier. The length of this code challenge should be 43 characters.

* Not all API clients is required to use PKCE. We still recommend to include this.

code_challenge_method Required* Set this parameter's value to s256. Note that plain is not supported.

* Not all API clients is required to use PKCE. We still recommend to include this.

The sample URL below shows a redirect to RamBase authorization server for an application requesting permission to submit YouTube Data API requests on the user's behalf:

https://api.rambase.net/oauth2?
client_id=yO6wK-6abcKlRHh2L7HtWw1&
state=T_nCih9WAEy_0-Ir4&
code_challenge=XXXXXXXX&
code_challenge_method=s256&
response_type=code&
redirect_uri=https://www.myapp.com/auth2callback

3.1.2. Step 2

RamBase authorization server will display the name of your application and the RamBase services that it is requesting permission to access on the user's behalf. The user can then consent or refuse to grant access to your application.

3.1.3. Step 3

After the user consents or refuses to grant access to your application, RamBase will redirect the user to the redirect_uri that you specified in step 1.

If the user granted access to your application, RamBase will have appended a code parameter to the redirect_uri. This value is a temporary authorization code that you can exchange for an access token as discussed in step 4.

http://localhost/oauth2callback?code=4/ux5gNj-_mIu4DOD_gNZdjX9EtOFf

If the user refused to grant access to your application, RamBase will have included the access_denied error message in the query parameters of the redirect_uri:

http://localhost/oauth2callback?error=access_denied

3.1.4. Step 4

Assuming the user has granted access to your application, exchange the authorization code obtained in step 3 for a refresh token and access token. To do so, send a POST request to https://api.rambase.net/oauth2/access_token that includes the following key-value pairs in the request body:

code Required The authorization code that RamBase returned to your redirect_uri in step 3.
client_id Required The OAuth 2.0 client ID for your application.
client_secret Required The client secret associated with your client ID.
redirect_uri Required A registered redirect_uri for your client ID
grant_type Required Set this value to authorization_code
code_verifier Required* The code_verifier which was created in step 1. Should be between 43 and 128 characters long.

* Not all API clients is required to use PKCE. If you still included the code_challenge in step 1 you are required to include the code_verifier.

A sample request is displayed below:

POST /oauth2/access_token HTTP/1.1
Host: api.rambase.net
Content-Type: application/x-www-form-urlencoded
code=23243_mIufsdfs33_djX9EtOFf&
code_verifier=XYXYXYXYXY&
client_id= yO6wK-6abcKlRHh2L7HtWw1&
client_secret=hDBmMRhz7eJRsM9Z2q1oFBSe&
redirect_uri=http://localhost/oauth2callback&
grant_type=authorization_code

3.1.5. Step 5

RamBase will respond to your POST request by returning a JSON object that contains a short-lived access token and a refresh token.

{
    "access_token" : "ya29.AHES6ZTtm7SuokEB-R",
    "token_type" : "Bearer",
    "expires_in" : 3600,
    "refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3"
}

Your application should store both values. It’s very important to keep the client_secret secret. It should therefore never be sent to the client. The Calling the RamBase API section explains how to submit an authorized request using the access token. The Refreshing an access token section explains how to use the refresh token to obtain a new access token if the one that you have expires.

3.2. Client-side web application flow

This flow is designed for JavaScript-based web applications that cannot maintain state over time. The following steps explains how to get an access token when using the client-side application flow.

3.2.1. Step 1

When a user first tries to perform an action that requires API authentication, direct the user to RamBase's authorization server at https://api.rambase.net/oauth2. The authorization server will refuse HTTP connections because it is only accessible over SSL (HTTPS). It supports the following URL parameters:

client_id Required The OAuth 2.0 client ID for your application. Hatteland Computer will give you this when you register your application as a client
redirect_uri Required A registered redirect_uri for that client ID.
response_type Required Set this parameter's value to token.
state Optional Any string that your application would use to maintain state between the request and redirect response. Your application will receive the same value that it sends for this parameter. For example, you could use this parameter to redirect the user to a particular resource in your application

The sample URL below shows a redirect to RamBase's authorization server for an application requesting permission to Rambase data on the user's behalf:

https://api.rambase.net/oauth2?
client_id=1084945748469-g34imk572&
redirect_uri=http://localhost/oauth2callback&
response_type=token

3.2.2. Step 2

RamBase's authorization server will display the name of your application and the RamBase services that it is requesting permission to access on the user's behalf. The user can then consent or refuse to grant access to your application.

3.2.3. Step 3

After the user consents or refuses to grant access to your application, RamBase will redirect the user to the redirect_uri that you specified in step 1.

If the user granted access to your application, RamBase will have appended a short-lived access token in the hash fragment of the redirect URI. The response will also include the expires_in and token_type parameters. These parameters describe the lifetime of the token in seconds and the kind of token that is being returned, respectively. Finally, the response will include the state parameter if a state parameter was included in the original request to the authorization server.

http://localhost/oauth2callback#
access_token=34fd3dfwww32&
token_type=Bearer&
expires_in=3600

JavaScript code running on your page can capture the access token from the window.location.hash value and store the token in a cookie for later use.

If the user refused to grant access to your application, RamBase will have included the access_denied error message in the query parameters of the redirect_uri:

http://localhost/oauth2callback?
error=access_denied

3.3. Resource Owner Password Flow

Because the resource owner’s password is exposed to the application, this flow should be used sparingly. It is recommended only for first-party “official” applications released by JHC. If this flow is used to access a customer’s resources (CNT) it would be OK to use this flow also for third-party applications.

In this flow the client itself ask the user for their username and password. The application then makes either a client side or server side request to the RamBase authorization server. If the username and password is correct you will get back an access token.

The following steps explains how to get an access token when using the resource owner password flow.

3.3.1. Step 1

When a user has entered his username and password you should make a POST request to the RamBase authorization server at https://api.rambase.net/oauth2/access_token. The authorization server will refuse HTTP connections because it is only accessible over SSL (HTTPs). You should provide the following parameters:

client_id Required The OAuth 2.0 client ID for your application.
client_secret Required The client secret associated with your client ID.
username Required The username entered by the user
password Required The password entered by the user
grant_type Required Set this value to password
target Optional This is in most cases optional. Use this parameter to specify RamBase target (eg. HATTELAND, JHCDEVSYS). If not provided and the user only have access to one target, the target will be automatically set. If the user has access to multiple targets, you will get 401 Unauthorized and a list of allowed targets.
otp Optional If you login using pid and password you will also need a “one time password” (OTP) if you are outside a “safe zone”. The OTP number is sent as an email or SMS to the user, when it is required.
endclientip Optional If you perform a login where you need to forward the Ip address of the end user, this value will override the client ip address. This will only be necessary if the ip of the server differs from the ip of the end user. This will only work if the host ip is within a trusted ip range.

A sample request is displayed below:

POST /oauth2/access_token HTTP/1.1
Host: api.rambase.net
Content-Type: application/x-www-form-urlencoded

client_id= yO6wK-6abcKlRHh2L7HtWw1&
client_secret=hDBmMRhz7eJRsM9Z2q1oFBSe&
username=4659&
password=so334DED33A&
grant_type=password

3.3.2. Step 2

RamBase will respond to your POST request by returning a JSON object that contains a short-lived access token and a refresh token.

{
    "access_token" : "ya29.AHES6ZTtm7SuokEB-R",
    "token_type" : "Bearer",
    "expires_in" : 3600,
    "refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3"
}

3.3.3. Step 3

If the target is not specified and the user have access to multiple targets, a list of the targets that the user have access to is returned.

{
    "message" : "Please provide a valid target",
    "allowed_targets" : "HATTELAND,HATTELAND_TEST"
}

3.4. Client Credentials Flow

This flow should be used when the application is acting on behalf of the application itself, and not on a specific user. This flow should not be used if the client_secret cannot be kept 100% secret. Because of that you can never use this from a client-side application.

The following steps explains how to get an access token using the client credentials flow.

3.4.1. Step 1

The application needs to request an access token from the RamBase authorization server, authenticating the request with its client credentials. A POST request is sent to https://api.rambase.net/oauth2/access_token. The authorization server will refuse HTTP connections because it is only accessible over SSL (HTTPs). You should provide the following parameters:

client_id Required The OAuth 2.0 client ID for your application.
client_secret Required The client secret associated with your client ID.
grant_type Required Set this value to client_credentials.
customerid Optional The customer you want this login to be associated with.
supplierid Optional The supplier you want this login to be associated with.
endclientip Optional If you perform a login where you need to forward the Ip address of the end user, this value will override the client ip address. This will only be necessary if the ip of the server differs from the ip of the end user. This will only work if the host ip is within a trusted ip range.

A sample request is displayed below:

POST /oauth2/access_token HTTP/1.1
Host: api.rambase.net
Content-Type: application/x-www-form-urlencoded

client_id= yO6wK-6abcKlRHh2L7HtWw1&
client_secret=hDBmMRhz7eJRsM9Z2q1oFBSe&
grant_type=client_credentials

3.4.2. Step 2

RamBase will respond to your POST request by returning a JSON object that contains a short-lived access token. You will not get a refresh token. To obtain a new access token when the existing one expires just go back to step 1 and request an access token in the same way you did the first time.

{
    "access_token" : "ya29.AHES6ZTtm7SuokEB-R",
    "token_type" : "Bearer",
    "expires_in" : 3600
}

4. Two-factor authentication

If a user is trying to login within a "trusted" zone, where no OTP is required, the login can be done in one single POST request with no need for two-factor authentication. This requires that the Target is specified or that the user only have access to one Target, in which case it will automatically try to login in to said Target.

If the user is trying to login outside a "trusted" zone, where an OTP is required, the following result will be returned to notify the application that OTP is required. When this is returned, an OTP has been sent to the users mail address or by SMS.

{
    "message " : "Please provide One Time Password",
    "allowed_targets " : "HATTELAND,HATTELAND_TEST",
    "otp_required" : true
}

5. Making requests to the RamBase API

After obtaining an access token for a user, your application can use that token to submit authorized API requests on that user's behalf. The API supports two ways to specify an access token:

HTTP request header (recommended): Specify the access token as the value of the Authorization: Bearer HTTP request header:

GET /sales/customers HTTP/1.1
Host: api.rambase.net
Authorization: Bearer ACCESS_TOKEN
...

Query parameter: Specify the access token as the value of the access_token query parameter:
https://api.rambase.net/sales/customers?$access_token=ACCESS_TOKEN

We don’t recommend sending access token via URL query parameters for the following reasons:

  • Logged URLs can leave tokens exposed if those logs were to become compromised
    Browsers, web servers, and other software may not adequately secure URLs in the browser history, web server logs, and other data structures. Any service that is logging URLs is now responsible for the security of your application’s tokens. If access tokens are passed in page URLs, attackers might be able to steal them from the history data, logs, or other unsecured locations.
  • End users have easy access to tokens
    This could mean your tokens are shared accidentally by an unknowing user (copy/pasting), or gamed in a social engineering attack, putting the security of your tokens in the hands of your end-users.
  • Query parameter length limit
    Both our API and browsers have limits on the length of URLs. By sending access token as HTTP header you will free up space for other query parameters.

The API will return an HTTP 401 response code (Unauthorized) if you submit a request to access a protected resource with an expired access token. The following section explains how to refresh an access token.

6. Refreshing an access token

If your application obtains a refresh token during the authorization process, then you will need to periodically use that token to obtain a new, valid access token. Server-side web applications, installed applications, and devices all obtain refresh tokens.

At any time, your application can send a POST request to RamBase's authorization server that specifies your client ID, your client secret, and the refresh token for the user. The request should also set the grant_type parameter value to refresh_token.

client_id Required The OAuth 2.0 client ID for your application. Hatteland Computer will give you this when you register your application as a client
client_secret Required The secret you got from JHC when you registered the application.
grant_type Required Set this parameter's value to refresh_token.
refresh_token Required The refresh token key you obtained during the authorization process.

The following example demonstrates this request:

POST /oauth2/access_token HTTP/1.1
Host: api.rambase.net
Content-Type: application/x-www-form-urlencoded

client_id= yO6wK-6abcKlRHh2L7HtWw1&
client_secret=qeehXh1SlUNgvyWGwDk1Edd&
refresh_token=336BMfW9j53gdGImsixUH&
grant_type=refresh_token

The authorization server will return a JSON object that contains a new access token and a new refresh token:

{
    "access_token" : "HES6ZTtm7SuokEB-R",
    "token_type" : "Bearer",
    "refresh_token" : "as6BMfW9j53gdGImsixUH",
    "expires_in" : 3600
}

7. Change target system

In some cases the API client is granted access to several RamBase systems. In these cases you need to provide the target-parameter during the authorization process. After successful authorization it might be useful to change RamBase system without going through the authorization process again.

To do so, send a POST request to https://api.rambase.net/oauth2/access_token that includes the following key-value pairs in the request body:

client_id Required The OAuth 2.0 client ID for your application. Hatteland Computer will give you this when you register your application as a client
client_secret Required The secret you got from JHC when you registered the application.
grant_type Required Set this parameter value to access_token.
access_token Required The access token key you obtained during the authorization process.
target Required Name of the RamBase system you want to change to.

The following example demonstrates this request:

POST /oauth2/access_token HTTP/1.1
Host: api.rambase.net
Content-Type: application/x-www-form-urlencoded

client_id= yO6wK-6abcKlRHh2L7HtWw1&
client_secret=qeehXh1SlUNgvyWGwDk1Edd&
grant_type=access_token&
access_token=336BMfW9j53gdGImsixUH&
target=RAMBASESYSTEMNAME

The authorization server will return a JSON object that contains a new access token and a new refresh token:

{
    "access_token" : "HES6ZTtm7SuokEB-R",
    "token_type" : "Bearer",
    "refresh_token" : "as6BMfW9j53gdGImsixUH",
    "expires_in" : 3600
}

8. Native applications

If you create a native client application you can use the client-side web application flow, but then you will only be given a short-lived access token and no refresh token. This means that you will not be able to create an application which allows the user to stay logged in for a long time.

It’s is extremely important that you don’t use the server-side web application flow in a native application because there is no way you can keep the client_secret secret for the user of your application. If your application requires users to stay logged in for a long time you have to have a server-side backend for your application, and use server-side web application flow from the server side.

A challenge with oauth in a native client is to show the login page which is html based and needs to be displayed in a browser. A solution to this problem is to embed a browser in your application. When you use the server-side web application flow you will need to register a redirect uri. This is the uri which will be requested when the user accepts the login.

In a native app you don’t have a web server you can redirect to. In this case there is a special redirect uri you can use urn:ietf:wg:oauth:2.0:oob. If you use the callback uri the RamBase api will redirect the browser to a new page where the authorization code is displayed. This page will instruct the user to copy this code and paste it into your application. If you don’t want to have any manual interaction with the user the authorization code is also displayed in the title of the page like this Success code=dfdse43434fd532fdfsd23442342. Your application can then parse this code from the title automatically and the close the page without showing it to the user.

When you have the code you can send it to the server-side backend which will in the next turn send it to the RamBase authorization server to exchanging it for an Access token.