Session service
Api Reference Guide
cURL Javascript

Introduction

Welcome to the AssetWise Session service API!

Session service is used for the purpose of authentication within AssetWise common services. A user can have multiple session where each session consists of an authentication token and the context of user, which can be used to limit what a user sees. Session uses OIDC authentication to authenticate users when login to the service.

Using the API

Users access the API by invoking an HTTP request method, most commonly GET or POST, to act on a resource. An HTTP request to the Session service can include parameters, while HTTP headers pass additional information to and from the server. However, a request will only return information through an authenticated session. If a client does not first authenticate against a server, the server response is 401: Unauthorized.

Acquire tokens

In this document we are going to address the questions related to the following topics:

  1. Session token.
  2. OIDC queries:
    1. How to register an IMS account.
    2. How to register an OIDC client secret.
    3. How to set up scopes/claims/permissions.
    4. How to generate a token from an OIDC client secret.
    5. How to generate a token from an IMS username and password.
  3. Session middleware.

Session token

Q: What are the different authentication methods and when one should be used over another? (Interactive IMS accounts vs OIDC client secrets and any others)

A: It depends on the kind of implementation that you want to have in your service.

Use one of the following methods:

  1. If you want to add the session login UI, then use SessionUI NuGet package. Check authentication section for more details.

  2. If you want to login but don’t want to consume the SessionUI package, use Session's /Account/Login endpoint. Check authentication section for more details.

  3. If you have client credentials with session scope and have generated an OIDC token, then use /Session/Open or /Session/Service/Open endpoints. Check solution for how to use open endpoints for more details.

  4. If you have a username and a password, then again you can use one of the login mechanisms (No. 1 or 2) according to your needs.

  5. If you have only a session token or an OIDC token, then you can use /Session/Open or /Session/Service/Open endpoints. Check solution for how to use open endpoints for more details.

  6. If you have an OIDC token, but your endpoint needs a session token to authenticate, then use session middleware to get the desired result.

Q: How does one obtain a session token (using login/sign in button)?

A: The key thing to understand is that all the AssetWise services require a "session token". This token goes into the authentication header for all requests.

The question is then - how does one obtain a session token?

There are a few ways. But first it is important to understand that that we never want the AssetWise service to know your credentials. Instead we depend on the Identity Management Service (IMS) to securely deal with that. IMS in turn uses OAuth (OIDC) flow to exchange your credentials for an "AccessToken" and the AssetWise Session service then turns that into a SessionToken. When using the browser, the Session service creates a _session cookie for convenience.

You can think of a session token as something that encapsulates your IMS access token plus some additional information, e.g. the default context, settings, Power BI.

In some service's Swagger page that's using Session service (like DataStorage or Session), you can press the "Sign In" button. It will redirect you to Session service, which will (if needed) redirect you to IMS.

Sign in button in the Swagger page

The easiest way to get going is to sign in via the web either using the service which is using Session service (like DataStorage) or directly with Session service. Then either use the Session service's Swagger UI to echo back the session token, or send an HTTP GET request to https://session.{your domain}.bentley.com/Session/Token. This method works because the _session cookie is available for all services on that domain.

It will return something like this:

{
  "value": "{SessionToken}",
  "scope": "session",
  "label": "session",
  "expiresAt": "1606873564"
}

The value above represents the session token. Put it in the header of API requests as a "Bearer Token". Example using PowerShell:

# Login to Session service (at https://eus.aw-cs-eap.bentley.com)
# Once logged in, you can yet your session token from https://session.{your domain}.bentley.com/Session/Token?tokenLabel=session
$sessionToken = "{SessionToken}"

# Then use the session token in the header
$headers = @{
    "Authorization" = "Bearer $sessionToken"
}

# Make a simple GET request
$result = Invoke-WebRequest -Uri "{your service URL}" -Method GET -Headers $headers

# And print it
$result.Content

Q: How and when to use the /Session/Open or /Session/Service/Open endpoints?

A: /Session/Service/Open endpoint should be used when you have either an unexpired OIDC token, or a session token, which will be expired in 5 minutes.

It is important to know that the .../Open endpoints are used to open or create a new session token. If a session token which is about to expire is provided, the new session token with an expiry of 60 minutes will be created and returned to the user along with the expiry time.

If you are using an OIDC token, add the token to the auth header and call the https://session.{your domain}.bentley.com/Session/Service/Open?save=true endpoint. It will return the session token along with the expiry:

{
  "sessionToken": "{SessionToken}",
  "expiresAt": "{ExpirationTime}"
}

OIDC

Q: How do I register an IMS account or how do I register an OIDC client secret?

A: IMS team handles this. Session service is not responsible for the creation of IMS accounts or OIDC client IDs and secrets.

Q: How do I set up scopes/claims/permissions?

A: If the scopes are for of creating client credentials, then contact the IMS team. Session is not responsible for creating a client.

But if your service needs some scopes to be added in the Session client so that it helps to access certain services, then contact Session service team for such an addition.

Q: How do I generate a session token from an OIDC client secret?

A: Firstly, if you have client credentials, then they should have a session scope as one of its scopes. You can't directly use the client credentials to obtain a session token, you first need to obtain the OIDC token. After you have an OIDC token, then you can call either /Session/Open or /Session/Service/Open endpoints to create a session.

Note: to get the required scopes for Session service and for different environments, please contact the Session service's team.

Q: How do I generate a token from an IMS username and password?

A: Use the login mechanism.


Session middleware

Q: When should Session middleware used?

A: Session middleware should be used when:

  1. You don't want to login to session.
  2. You already have an OIDC token with a session scope.
  3. You want to authenticate an endpoint using a session token, but also have an OIDC token. It will:
    1. Validate the token given to you.
    2. Exchange a valid token with a session token.

Manage token lifetimes

This document will deal with questions related to tokens and their lifetimes and how to keep a session alive. This also addresses the questions related to session cookies.

Q: What is the validity of a session token or an IMS token?

A: Session tokens and IMS tokens are valid for 60 minutes.

Q: What is the validity of a refresh token?

A: 30 days.

Q: How to get the expiration date for my session token or access token?

A: You can use one of these methods:

  1. If you have the token, then it can be decoded to check the expiry (exp) value.
  2. You can get both session and access token's expiry by using the /Session/Token endpoint and specifying session as the label for Session tokens or BentleyAccess for IMS access tokens.
  3. If you are using one of the .../Open endpoints to get the session token, then you can find the expiry of the session token in the response.

Q: How to get the expiration date of a refresh token? A: Use the /RefreshTokenStatus endpoint.

# Set the header with either a session or an OIDC token
$headers = @{
    "Authorization" = "Bearer $token"
}

# Call the /RefreshTokenStatus endpoint (no parameters are required)
$result = Invoke-WebRequest -Uri "https://session.{domain}/RefreshTokenStatus" -Method GET -Headers $headers

The result of this endpoint is either a true or a false value. True indicates a valid refresh token and false indicates that there are no active refresh tokens for that user.

Q: How to keep a session alive?

A: Choose one of these methods depending on your situation:

  1. If you want to use the session for long running background jobs, which run for more than 60 minutes, use a refresh token provided by the Session service. Session service does not automatically get a new access token using the refresh token. When using it you won't need to login again to get a new access token (IMS or session token), instead call /Session/Token to get a new access token from IMS and subsequently create a session token using the access token. Check the section for refresh tokens to get more details.

Note: access tokens acquired through refresh tokens also have a validity of 60 minutes. Their benefit is that you won't have to login again for the duration a refresh token is valid for (30 days) and use /Session/Token endpoint to get new access token.

  1. When you are not using a refresh token, then you'd need to get a new token every 60 minutes, you need to consider the following:
    1. If you just need a session token to be renewed - use the /Session/Service/Open endpoint when the token is about to expire. Check the acquire token section for more details on .../Open endpoints.
    2. If you want to renew the pair of tokens (IMS + session token), then login again after expiration of token. Login operation can either be done using the sign in button or the /Account/Login endpoint. Check authentication section for more details.

Q: How to get or set cookies in a session?

A: If you are using the SessionUI package, then cookies are set automatically by the Session service. But if you are using the /Account/Login endpoint to login, then you will need to set the cookies explicitly. Session uses the following endpoints to set and get cookies:

  1. To set cookies: make a POST request to this URL: https://session.{domain}.bentley.com/cookie/set with two arguments: value and return URL.

    1. value - indicates the value of the cookie. In Session service, the name of the cookie is _session.
    2. returnUrl - it's optional, indicates the value of return URL.
  2. To get cookies: the /GetCookie endpoint is a method to retrieve the encrypted cookie, currently signed in on the Session service domain. The user must be already signed in for the endpoint to retrieve the cookie. The endpoint accepts one required argument - ReturnUrl an optional callback path parameter. The return URL specifies where user will be redirected after cookie is set on the remote host. The callback parameter specifies where the form with cookie data is posted. If the callback parameter isn't set, it will be set to cookie controller set action and the form will be posted with cookie value and return URL.

Authentication

Authentication in Session service can be done in several ways listed below.

Using the /Account/Login endpoint

Call this endpoint and provide the value of returnUrl of your service. In the following example, Session service is calling the /Account/Login endpoint and then redirects to Session's Swagger page: https://session.{domain}/account/login?ReturnUrl=https://session.{domain}/swagger/index.html. After calling this endpoint, the user will be redirected to the login page from IMS (environment specific) and after a successful authentication, the session JWT is added to the HTTP context. We can use cookies to store the session JWT.

Using the Nuget package

Use the Bentley.Extensions.SessionUI and Bentley.Extensions.BackplaneUI packages to add a sign in button to your service. Visit Session service's README for more information.

If you click the sign in button, you will be redirected to the login page from IMS.

Using Session middleware

We can use the Session middleware to authenticate the user by using the Bentley.Extensions.Session.Authentication Nuget package. It allows for authentication without using SessionUI. Visit Session middleware docs for more information.


If a user has an OIDC token, then a new session can be opened by using the /Session/Service/Open or /Session/Open endpoints. To obtain an OIDC token that can be passed to Session service using client credentials, the user should create it with a Session scope. Contact the Session service's team to get the value of the required scope.

# Login to Session service at https://session.{domain}
# Once logged in, you can yet your session token from
# https://session.{domain}/Session/Token?authority=https://qa-ims.bentley.com&label=session
$sessionToken = "{generatedSessionToken}"

# Then use the session token in the header
$headers = @{
    "Authorization" = "Bearer $sessionToken"
}

# Call the Session service
$result = Invoke-WebRequest -Uri "https://session.{domain}/Session" -Method GET -Headers $headers

# Display the results
$result.Content

Authenticating client connections to the server requires three steps.

  1. Call the IMS Authority Service to obtain an IMS access token.
  2. Pass the IMS access token to the Session service to obtain a session bearer token.
  3. Parameterize the session bearer token into a Session service HTTP request header.

Session service expects a session token or an OIDC token to be included in all API requests to the server in an authorization header: Authorization: {sessionToken}

You must replace sessionToken with the token obtained from the Session service.

Refresh tokens

A refresh token is a token that can be used to acquire new access tokens. The lifetime of a refresh token is much longer compared to that of an access token. Refresh tokens can also expire, but are quite long-lived. When the current access token expires or becomes invalid, Session service provides the refresh token to IMS to obtain a new access token. The user needs to explicitly provide consent to acquire a refresh token in this manner.

To provide consent for the refresh token:

  1. Login to Session service.
  2. Click on the avatar icon on the top right corner.
  3. If the toggle for "Background tasks" is turned on, that means there already is a valid refresh token present. If it is turned off, click on it to turn it on. The amber color dot on the avatar icon indicates that no valid refresh token is present.
  4. After clicking the "Background tasks" option, a "Request for Approval" page will open. Click "Allow".

Pass the session token in the authorization header to the request. "Authorization" = "Bearer {sessionToken}"

# To use a refresh token 
$sessionToken = "{sessionToken}"

# Then set the SessionToken to Authorization header
$headers = @{
    "Authorization" = "Bearer $sessionToken"
}

# Call the /Session/Token endpoint with forceRefresh set to true
$result = Invoke-WebRequest -Uri "https://session.{domain}/Session/Token?authority=https://qa-ims.bentley.com/&tokenLabel=BentleyAccess&forceRefresh=true" -Method GET -Headers $headers

# Display the results
$result.Content

Valid /Session/Token endpoint query parameters:

Parameter Description
authority Authority. Default is the IMS authority. E.g. on DEV - https://qa-ims.bentley.com/.
label Scope of the requested token. Optional parameter. Default is - session (when both label and tokenLabel are left empty).
tokenLabel Label of the requested token. Optional parameter. Default is - session (when both label and tokenLabel are left empty).
forceRefresh Set to true to use the refresh token to get a new access token. Default is false. For continuous request with true value, it would return the same token if there is an existing token that's valid for >= 55 min.

Either label or tokenLabel must be specified. We recommend to use tokenLabel instead of label. You can use both the parameters as well, but that is not required.

Note: label is a unique name provided to each token stored for any account. BentleyAccess is the default label for the IMS access token, which is created using Session service's IMS client (using Session service login).

PAT

A PAT (Personal access token) is used as a reference token to get any token from Session service. If you have a backend process that cannot prompt for credentials, for that flow we provide the personal access token functionality. The key notion here is that the user creates a “key” (which doesn't contain their credentials). This key can be exchanged later for other tokens (such as an access token, session token, etc).

Creating PATs

# To create a PAT
$sessionToken = "{generatedSessionToken}"

# Then set the session token to the authorization header
$headers = @{
    "Authorization" = "Bearer $sessionToken"
}

# Call the CreatePAT endpoint
$result = Invoke-WebRequest -Uri "https://session.{domain}/CreatePAT?label=BentleyAccess&expiry=1" -Method PUT -Headers $headers

# Display the results
$result.Content

Here are the /CreatePAT endpoint's available query parameters:

Parameter Description
label Label of the token, to associate it with the PAT (e.g. BentleyAccess). For multiple tokens, enter comma seperated list of labels (e.g. BentleyAccess, session).
expiry Validity of the PAT token, in number of days.

Pass the session token in the authorization header to the request.

A successful request will return the PAT's value and ID.

{
  "id": "29d31b17-ea94-c69e-efe9-eccd2ee4a778",
  "pat": "{PAT}"
}

Save the response of the /CreatePAT endpoint to use it later. There is no other way to get the PAT and its value. If it is lost, you would need to create a new PAT.

label is a unique name provided to each token stored for any account. BentleyAccess is the default label for the IMS access token which is created using Session service's IMS client (using Session service login).

To create a PAT for the session token, use the session label. You can also attach multiple tokens to the same PAT. To attach both session and the access tokens to a single PAT, use comma seperated values for the label. E.g. BentleyAccess, session.

All the labels are case sensitive.

If you are creating a PAT for the session token, then PAT would be created for the same context as the session token used in the authorization header to request /CreatePAT endpoint.

Using PATs

# To use an existing PAT
$PAT = "{PAT}"

# Then set the PAT as the authorization header
$headers = @{
    "Authorization" = "Token $PAT"
}

# Call the /Session/Token/PAT endpoint
# patToken and cyclePat are optional parameters. patToken parameter is not
# required when we pass the PAT in the authorization header. cyclePat is by
# default set to true, which means the PAT will get invalidated after single use
# and a new PAT will be returned in the response for the next use.
$result = Invoke-WebRequest -Uri "https://session.{domain}/Session/Token/PAT?tokenLabel=BentleyAccess" -Method GET -Headers $headers

# Display the results
$result.Content

Here are the /Session/Token/PAT endpoint's available query parameters:

Parameter Description
patToken A valid PAT.
tokenLabel Label of the requested token (e.g. BentleyAccess).
cyclePat Set true if you want to cycle the PAT, else set false if you want to use the same PAT until it expires. Default value is true.

To get an access token using a PAT, use BentleyAccess as the token label. To get a session token using a PAT, use session as the token label.

There are two ways to make requests to this endpoint:

  1. Pass the session token in the authorization header to the request. In this case, the patToken parameter is required: "Authorization" = "Bearer {sessionToken}".

  2. Pass the PAT in the authorization header to the request. In this case the patToken parameter is not required: "Authorization" = "Token {PAT}".

A successful request will return a JSON object:

Key Description
access_token Requested token.
expires_in Remaining time for the token expiry in seconds.
auth_guid PAT to use for the next request.

Get a session token from a BentleyAccess token

# Use the BentleyAccess token
$BentleyAccess = "{BentleyAccess_token}"

# Then set the BentleyAccess token to Authorization header
$headers = @{
    "Authorization" = "Bearer $BentleyAccess"
}

# Call the /Session/Open endpoint
# Context is an optional parameters. If 'context' parameter is empty, then it
# will return the session token for the default context and if set to a valid
# context ID, then it will return session token for that specific context.
$result = Invoke-WebRequest -Uri "https://session.{domain}/Session/Open" -Method PUT -Headers $headers

# Display the results
$result.Content

Get a new session token from a BentleyAccess token

Call the /Session/Open?context={context_guid} endpoint. The context query parameter must be a valid context ID. It is a optional parameter. If kept empty, the default context will be used. Pass the session token in the authorization header to the request. "Authorization" = "Bearer {BentleyAccess_token}"

A successful request will return a JSON object:

Key Description
sessionToken Requested session token.
expiresAt Expiry in the UNIX timestamp.

Revoking PATs

To revoke an existing PAT, make a request to /RevokePAT?patId=<PAT_ID>. Pass a session token in the authorization header to the request: "Authorization" = "Bearer {sessionToken}"

# To revoke a PAT
$sessionToken = "{sessionToken}"

# Then set the session token in the authorization header
$headers = @{
    "Authorization" = "Bearer $sessionToken"
}

# Call the /RevokePAT endpoint
$result = Invoke-WebRequest -Uri "https://session.{domain}/RevokePAT?patId=f6fd1fa7-7e8..." -Method DELETE -Headers $headers

# Display the results
$result