Authentication

General

Protime implements OIDC (Open ID Connect) protocol to authenticate a user.

https://authentication.<environmentURL>/tenants/<tenantName>/.well-known/openid-configuration

  • <environmentURL>
    • Production: myprotime.eu
    • Sandbox: myprotimesandbox.eu
  • <tenantName>

OAuth 2.0 Client Credentials Flow

The following diagram illustrates the OAuth 2.0 client credentials flow used for authentication:

  sequenceDiagram
    participant Client as Your Application
    participant Auth as Authentication Server
    participant API as Protime API

    Client->>Auth: POST /connect/token
    Note over Client,Auth: grant_type=client_credentials<br/>client_id=xxx<br/>client_secret=xxx<br/>scope=xxx
    Auth-->>Auth: Validate credentials
    Auth-->>Client: Access Token (JWT)<br/>expires_in: XXXX seconds
    
    Client->>API: API Request
    Note over Client,API: Authorization: Bearer {token}
    API-->>API: Validate token
    API-->>Client: API Response (200 OK)
    
    Note over Client,API: Token valid for XX minutes

Get an access token

To get an access token for our application, you need to send a POST request to

https://authentication.<environmentURL>/tenants/<tenantName>/connect/token

These tokens will be per tenant. A token will be valid for a set amount of minutes, which is given in the response in seconds.

Request Details

Headers:

{
	"Content-Type":"application/x-www-form-urlencoded"
}

Body (x-www-form-urlencoded):

{
	"grant_type":"client_credentials",
	"client_id":"client specific client id",
	"client_secret":"client specific client secret",
	"scope":"connector-protimeapi-activity-definitions.read connector-protimeapi-activity-definitions.write connector-protimeapi-clockings.read"
}

Response:

{
	"access_token":"eyJ...Uc",
	"expires_in":1800,
	"token_type":"Bearer",
	"scope":"connector-protimeapi-activity-definitions.read connector-protimeapi-activity-definitions.write connector-protimeapi-clockings.read"
}

Use the access token

Set the bearer token in your Authorization header for each request:

{
	"Authorization":"Bearer eyJ...Uc"
}

Best Practices:

Token expiration time

A token will be valid for a set amount of minutes, given in the response in seconds. Reuse this token for multiple api-calls instead of regenerating a token per request. This could result in rate limiting for the application.

If a bearer token is expired or not valid anymore, a response code of 401 will be returned on which a new token has to be generated to be able to use the API.

Tip

Use a token for multiple calls over a period as long as possible, but fetch a new one right before the expiration time. This way you avoid attempts with an invalid token first.

Scopes

A scope defines the specific permissions or access levels granted to a token. It determines what actions or data the token can access within the Protime API.
By default, when no scope is given, all the available scopes will be present on your token. However, to make it more secure, it is advised to narrow it down. Think about the granularity of these scopes when requesting access tokens.
The necessary scopes can be found with the endpoints in Swagger.

eg: only clocking-related scopes are needed
Body (x-www-form-urlencoded):

{
	"grant_type":"client_credentials",
	"client_id":"client specific client id",
	"client_secret":"client specific client secret",
	"scope":"connector-protimeapi-clockings.read connector-protimeapi-clockings.write"
}

Response:

{
	"access_token":"eyJ...Uc",
	"expires_in":1800,
	"token_type":"Bearer",
	"scope":"connector-protimeapi-clockings.read connector-protimeapi-clockings.write"
}