Authentication and Authorization
OAuth 2.0 is an open authorization protocol that enables applications to obtain access to user accounts on an HTTP service. It works by delegating user authentication to the service that hosts the user account and authorizing third-party applications to access the user account. Your server-side app will use OAuth libraries or endpoints to implement the OAuth 2.0 authorization that allows your apps to access CORE APIs. OAuth 2.0 lets application access specific user data without requiring access to a user's private credentials. It means that an application can use OAuth 2.0 to obtain permission from a CORE company admin to read and write data to their CORE company.
This OAuth 2.0 flow is designed to allow your app to access the CORE API whether the user is interacting with the application or not. For more information on OAuth, click here.
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows clients to verify the identity of the end-user based on the authentication performed by an authorization server as well as to obtain necessary profile information about the end-user in an interoperable and REST-like manner.
OpenID Connect allows clients of all types, including web-based, mobile, and JavaScript clients, to request and receive information about authenticated sessions and end-users. The specification suite is extensible, allowing participants to use optional features such as encryption of identity data, the discovery of OpenID providers, and session management when it makes sense for them.
OpenID Connect (OIDC) is an authentication protocol based on the OAuth 2.0 family of specifications. It uses simple JSON Web Tokens (JWT), which you can obtain using flows conforming to the OAuth 2.0 specifications.
While OAuth 2.0 is about resource access and sharing, OIDC is all about user authentication. By layering OpenID Connect on top of OAuth2, the identity semantic comes into play, and OAuth2 becomes identity aware, enabling things like single sign-on and personal profile information sharing.
Authenticating the user
Authenticating the user involves obtaining an ID token and validating it. ID tokens are a standardized feature of OpenID Connect designed for use in sharing identity assertions on the Internet.
Obtaining the token requires an authentication step where the users log in with their CORE account after which they are asked whether they are willing to grant the permissions that your application is requesting. This process is called user consent.
If users grant the permission, CORE Authorization Server sends your application an authorization code at the callback endpoint that you defined in the Redirect URI section of your app. This authorization code can be exchanged to obtain the ID token and access token. Because the access tokens have an expiry time, your app needs a new access token every time the old one expires. You can get a new access token by repeating the authorization steps and asking the users for consent again or you can use a refresh token to get a new access token behind the scenes. This bypasses the need to repeatedly ask the users for consent. To know more, check out Tokens.
Step 1: Authorization Request
Initiate the authorization process by redirecting the user to CORE Authentication server. The discussion here assumes the base URI is:
This endpoint is accessible over https; plain http connections are refused. Ensure query parameter values are always URL encoded. The set of query parameters supported by the CORE server include:
Parameter | Values | Description |
---|---|---|
client_id | The client ID you obtain from the developer portal dashboard | Required. Identifies which app is making the request. Obtain this value from the Keys tab on the app profile via My Apps on the developer site |
scope | Space-delimited set of permissions that the application requests | Required. Identifies the CORE API access that your application is requesting. The values passed in this parameter inform the consent screen that is shown to the user Available scopes include: read:core - Readonly access to company data readwrite:core - Full access to company data offline_access - To recieve a Refresh Token openid - Provides access to a user's details like name, address etc. profile - Provides access to a user's profile excluding address and email address - Provides access to address claim at the UserInfo endpoint email - Provides access to email claim at the UserInfo endpoint document:upload - Allows your app to use the Document Upload endpoint (if it has access) |
redirect_uri | One of the redirect URI values listed for this app in the developer portal dashboard | Required. Determines where the response is sent. The value of this parameter must exactly match one of the values listed for this app in the app settings. This includes the https scheme and the same case
|
response_type | code | Required. Determines whether the CORE API OAuth 2.0 endpoint returns an authorization code. Always set this to code
|
state | This field can be a Base64 encoded JSON object that can hold multiple values | Authorization protocols provide a state parameter. During authentication, the application sends this parameter in the authorization request, and the Authorization Server will return this parameter unchanged in the response. |
Example: A complete authorization request URI:
GET /connect/authorize?client_id=Q3ylJatCvnkYqVKLmkH1zWlNzNWB5CkYB36b5mws7HkKUEv9aI&response_type=code&scope=openid&redirect_uri=https://www.coredemo.com/oauth-redirect
Step 2: User Consent
In this step, the user decides whether to grant your application the requested access or not. At this stage, CORE displays a consent window with the name of your application and your CORE Company name, seeking permission to access with the user’s authorization credentials. The user can then consent or refuse to grant access to your application.
Your application doesn’t need to do anything at this stage as it waits for the response from CORE’s Authentication server indicating whether the access was granted or not.
Step 3: CORE Authentication Server Response
The response or code is sent to the redirect_uri that you specified in the request. All responses are returned in the query string, as shown below:
https://www.coredemo.com/oauth-redirect&code=45P7q7W91a-oMsCeLvIaQm6bTrgtp7
Note
The authorization code returned in the code query parameter. You are going to use it later in the flow.
Parameter | Description |
---|---|
Code | Authorization code returned |
State | Confirm that the state received from CORE matches the state token you sent in the authentication request |
This round-trip verification helps to ensure that a user and not a malicious script is making the request.
Error Responses
Certain error conditions trigger the single query parameter error, to be sent to the redirect URI.
Error response | Description |
---|---|
access_denied | The user did not authorize the request. |
invalid_scope | An invalid scope string was sent in the request |
Step 4: Exchanging Authorization Code for ID Token
Making the request
After the app receives the authorization code, it exchanges the code for an ID Token. The discussion here assumes the base URI is:
POST /connect/token
This endpoint is accessible over https; plain http connections are refused.
Field | Description |
---|---|
code | Required. The authorization code returned from the initial request |
redirect_uri | Required. One of the redirect URIs listed for this project in the developer portal |
grant_type | Required. As defined in the OAuth 2.0 specification, this field must contain a value of authorization_code |
client_id | Required. This is your application's Client ID |
client_secret | Required. This is your application's Client Secret (only required for confidential applications) |
Example: The actual request might look like the following.
The response is sent back as a json object given below:
Handling the response
A successful response to this request contains the following fields:
Field | Description |
---|---|
access_token | The token that is used to access the CORE APIs |
refresh_token | A token used when refreshing the access token |
refresh_token expires_in | The remaining lifetime, in seconds, for the connection, after which time the user must re-grant access. |
expires_in | The remaining lifetime of the access token in seconds. The value always returned is 3600 seconds (1 hour). Use the Refresh Token to get a fresh one |
token_type | Identifies the type of token returned. At this time, this field will always have the value 'Bearer' |
id_token | Returned for openid and associated user scopes for user authentication |
To know more about validating an ID Token: Click here
Discovery Document
The Discovery Document is a JSON document containing key-value pairs that provide details about the CORE authorization server. The information provided by the discovery document includes authorization URLs, token, endpoints, scopes and userinfo. You can find CORE’s discovery document on:
Server-Side Web Applications
For an app to access data in a CORE company, it must implement the OAuth 2.0 protocol for authorization. This document explains how web server apps use CORE OAuth endpoints to implement the OAuth 2.0 authorization workflow.
Essentials:
- Create a CORE Developer account and add your app: You must have a CORE Developer account and an app within that account. The app serves as a container for the OAuth workflow.
- Get client keys: Obtain OAuth 2.0 client keys from your app's dashboard. To locate the app's dashboard, sign in to the CORE Developer account. and click My Apps. From here, click the Keys tab.
- Define redirect URIs: On the app setting page, create one or more redirect URIs. These URIs handle responses or Code from the authorization server and are called after the user authorizes the connection. URIs in this list are the only ones to which the authorization response can be sent from the OAuth 2.0 server. You must define at least one URI specifically for your application's auth endpoint before you can use OAuth 2.0
Initiating the Authorization Request
Making the RequestInitiate the authorization process by redirecting the user to CORE OAuth 2.0 server. The discussion here assumes the base URI is:
This endpoint is accessible over https; plain http connections are refused. Ensure query parameter values are always URL encoded. The set of query parameters supported by the CORE server include:
Parameter | Values | Description |
---|---|---|
client_id | The client ID you obtain from the developer dashboard | Required. Identifies which app is making the request. Obtain this value from the Keys tab on the app profile via My Apps on the developer site. |
scope | These are the set of permissions that the application requests. Multiple scopes can be passed in a single request seperated by whitespace | Required. Identifies the CORE API access that your application is requesting. The values passed in this parameter inform the consent screen that is shown to the user. Available scopes include:read:core- Read only access to company data readwrite:core- Full access to company data openid- Provides access to a user's details like name, address, etc. profile- Provides access to a user's profile excluding address and email address- Provides access to address claim at the UserInfo endpoint email- Provides access to email claim at the UserInfo endpoint offline_access - To recieve a Refresh Token document:upload - Allows your app to use the Document Upload endpoint (if it has access) Note: To get access to the Document Upload endpoint, you need to send an email request to CoreDeveloper@bqe.com. |
redirect_uri | One of the redirect URI values listed for this project in the developer dashboard | Required. Determines where the response is sent. The value of this parameter must exactly match one of the values listed for this app in the app settings. This includes the https scheme, the same case.
|
response_type | code | Required. Determines whether the CORE API OAuth 2.0 endpoint returns an authorization code. Always set this to code.
|
state | This field can be a Base64 encoded JSON object that can hold multiple values | Authorization protocols provide a state parameter. During authentication, the application sends this parameter in the authorization request, and the Authorization Server will return this parameter unchanged in the response. Your application can use this parameter in order to make sure that the response belongs to a request that was initiated by the same user. Therefore, state helps mitigate CSRF attacks. Restore the previous state of your application |
Example: A complete authorization request URI:
GET /connect/authorize?client_id=Q3ylJatCvnkYqVKLmkH1zWlNzNWB5CkYB36b5mws7HkKUEv9aI&response_type=code&scope=readwrite:core&redirect_uri=https://www.coredemo.com/oauth-redirect
The response is sent to the redirect_uri that you specified in the request. All responses are returned in the query string, as shown below:
https://www.coredemo.com/oauth-redirect&code=45P7q7W91a-oMsCeLvIaQm6bTrgtp7
- The authorization code returned in the code query parameter. You use it later in the flow.
- Confirm that the state received from CORE matches the state token you sent in the authentication request. This round-trip verification helps to ensure that the user, not a malicious script, is making the request.
Certain error conditions trigger the single query parameter error, to be sent to the redirect URI.
Error response | Description |
---|---|
access_denied | The user did not authorize the request. |
invalid_scope | An invalid scope string was sent in the request |
Exchange Code for Refresh and Access Tokens
After the app receives the authorization code, it exchanges the authorization code for Refresh and Access Tokens. The discussion here assumes the base URI is:
POST /connect/token
This endpoint is accessible over https; plain http connections are refused.
Field | Description |
---|---|
code | Required. The authorization code returned from the initial request |
redirect_uri | Required. One of the redirect URIs listed for this project in the developer portal |
grant_type | Required. As defined in the OAuth 2.0 specification, this field must contain a value of authorization_code |
client_id | Required. This is your application's Client ID |
client_secret | Required. This is your application's Client Secret (only required for confidential applications) |
Example: The actual request might look like the following.
The response is sent back as a json object given below:
Handling the response
A successful response to this request contains the following fields:
Field | Description |
---|---|
access_token | The token that must be used to access the CORE APIs. |
refresh_token | A token used when refreshing the access token |
refresh_token expires_in | The remaining lifetime, in seconds, for the connection, after which time the user must re-grant access. |
expires_in | The remaining lifetime of the access token in seconds. The value always returned is 3600 seconds (one hour). Use the refresh token to get a fresh one |
token_type | Identifies the type of token returned. At this time, this field will always have the value Bearer |
Single Page Applications
Single-page apps (or browser-based apps) run entirely in the browser after loading the Javascript and HTML source code from a web page. As the entire source is available to the browser, they cannot maintain the confidentiality of a client secret. So the secret is not used for these apps. The flow is precisely the same as the authorization code flow, but at the last step, the authorization code is exchanged for an access token without using the client secret.
Authorization
The authorization code is a temporary code that a client exchanges for an access token. The code is obtained from an authorization server, where the user gets a chance to see what information the client is requesting and whether to approve or deny the request.
Step 1: Initiating the Authorization RequestThe first step of the flow is to initiate the authorization process by redirecting the user to CORE authorization server. The discussion here assumes the base URI is:
GET /connect/authorize?client_id=a17c21ed&response_type=code&state=5ca75bd30&redirect_uri=https://example-app.com/auth
Authorization Grant Parameters
The following parameters are used to make the authorization request.
Name | Value | Description |
---|---|---|
response_type | code | response_type is set to code indicating that you want an authorization code as the response |
client_id | The client ID you obtain from the developer portal dashboard | The client_id is the identifier for your app. You will have received a client_id when first registering your app on the CORE developer portal |
redirect_uri | One of the redirect URI values listed for this project in the developer portal dashboard | Required. Determines where the response is sent. The value of this parameter must exactly match one of the values listed for this app in the app settings. This includes the https scheme, the same case
|
scope | These are the set of permissions that the application requests. Multiple scopes can be passed in a single request seperated by whitespace | Required. Identifies the CORE API access that your application is requesting. The values passed in this parameter inform the consent screen that is shown to the user. |
state (recommended) | This field can be a Base64 encoded JSON object that can hold multiple values | Authorization protocols provide a state parameter. During authentication, the application sends this parameter in the authorization request. The Authorization Server returns this parameter unchanged in the response. Your application can use this parameter in order to make sure that the response belongs to a request that was initiated by the same user. Therefore, state helps mitigate CSRF attacks. Restore the previous state of your application |
The lack of using a client secret means that using the state parameter is even more important for single-page apps.
Step 2: User Consent
After the user visits the authorization page, CORE displays a log-in window. Enter you CORE credentials and click Login.
When logged in, CORE displays a consent dialog with the name of your application and CORE Company name, requesting permission to access with your authorization credentials including scope, etc.
If you click Grant Permission, the server redirects to the website with an authorization code and state value in the URL query string.
CORE does not allow you to log-in to multiple companies during a single client app instance.
Handling the Response
The response is sent to the redirect_uri that you specified in the request. All responses are returned in the query string, as shown below:
http://yourdemoapp.com?code=CODE
Step 3: Exchange the Authorization Code for an Access Token
To exchange the Authorization Code for an Access Token, the app makes a POST request to CORE’s token endpoint. The request will have the following parameters.
Name | Values | Description |
---|---|---|
grant_type | Authorization code | Required. The grant_type parameter must be set to “authorization_code“ |
code | Code value received | Required. This parameter is for the authorization code received from the authorization server, which is in the query string parameter “code” |
redirect_uri | One of the redirect URI values listed for this project in the developer portal dashboard | If the redirect URL was included in the initial authorization request, it must be included in the token request as well and must be identical |
Client_Id | The client ID you obtain from the developer portal dashboard | Required.Despite the client secret not being used in this flow, the request requires sending the client ID to identify the application making the request. This means the client must include the client ID as a POST body parameter |
Example: The request might look like the following.
The response is sent back as a json object given below:
Handling the Response
A successful response to this request contains the following fields:
Name | Description |
---|---|
access_token | The token that must be used to access the CORE APIs |
token_type | Identifies the type of token returned. At this time, the field will always have the value Bearer |
Expires_in | The remaining lifetime of the access token in seconds. The value always returned is 3600 seconds (1 hour) |
Id_token | Returned for openid and associated user scopes for user authentication |
Native Applications
If you are building a native application, the authorization code flow with a Proof Key for Code Exchange (PKCE) is the favored method for regulating the access between your application and a resource server.
PKCE describes a technique for public clients to reduce the threat of having the authorization code intercepted. The method involves the client first creating a code challenge and a code verifier, and then using that code verifier again when exchanging the authorization code for an access token. This way, if the authorization code is intercepted, it will not be useful as the token request relies on the initial challenge and the verifier.
Authorization Code Flow with PKCE is the standard code flow with an additional step at the beginning and an extra verification at the end.
When the native app begins the authorization request, instead of immediately launching a browser, the client first creates what is known as a ‘Code Verifier .‘ It 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.
After the app has generated the code verifier, it uses that to create the ‘Code Challenge.’ The code challenge is a BASE64-URL-encoded string of SHA256 hash of the code verifier.
A complete authorization request will include the following parameters.
Initiating the Authorization Request
GET /connect/authorize?response_type=code&client_id=bJyXzz6X4pY0Qc5EuvKXL9UZ1hvGvt3X.apps.bqe.com&redirect_uri=http://localhost/pkcetestapp&scope=readwrite:core&state=pcMYJ722TrooUTrk&code_challenge=2cWTIbQvY6MNnIK4J8-p1Bb_8gqvv7YSZGRllDyb7f4&code_challenge_method=S256
Authorization Grant Parameters
The following parameters are used to make the authorization request.
Parameter | Value | Description |
---|---|---|
response_type | Code | Response_type is set to code indicating that you want an authorization code as the response |
client_id | The client_id you obtain from the Developer Portal | The client_id is the identifier for your app. You will have received a client_id when first registering your app on the CORE Developer Portal |
redirect_uri | One of the redirect URI values listed for this project in the developer portal dashboard | Required. Determines where the response is sent. The value of this parameter must exactly match one of the values listed for this app in the app settings. This includes the scheme, the same case
|
scope | Required. Identifies the CORE API access that your application is requesting. The values passed in this parameter inform the consent screen that is shown to the user. Available scopes include: | |
State (recommended) | This field can be a Base64 encoded JSON object that can hold multiple values | Authorization protocols provide a state parameter. During authentication, the application sends this parameter in the authorization request. The Authorization Server returns this parameter unchanged in the response. |
code_challenge | The code challenge generated | Base64-URL-encoded string of SHA256 hash of the Code Verifier |
code_challenge_method | Whether the challenge is the plain verifier string or SHA256 hash of the string |
After you visit the authorization page, CORE displays a log-in window. Enter your CORE credentials and click Login.
When logged in, CORE displays a consent dialog with the name of your application and CORE Company name, requesting permission to access your authorization credentials including scope, etc.
If you click Grant Permission, the server redirects to the website with an authorization code and state.
CORE does not allow you to log-in to multiple companies amid a single client app instance.
Handling the response
The response is sent to the redirect URI specified in the request. All responses are returned in the query string as shown below:
https://www.coredemo.com/oauth-redirect&code=CODE
Step 3: Exchanging Authorization Code for an Access Token
To exchange the Authorization Code for an Access Token, the app makes a POST request to CORE token endpoint. The request has the following parameters:
Name | Values | Description |
---|---|---|
grant_type | Authorization Code | Required. The grant_type parameter must be set to ‘authorization_code’ |
code | Code value received | Required. This parameter is for the authorization code received from the authorization server, which is in the query string parameter ‘code’ |
redirect_uri | One of the redirect URI values listed for this project in the Developer Portal | If the redirect URI was included in the initial authorization request, it must be included in the token request as well and must be identical |
client_Id | The client id you obtain from the Developer Portal | This is the applications registered client id |
code_verifier | Cryptographically random string | The code verifier for the PKCE request that the app originally generated before the authorization request |
Example: The actual request might look like the following.
The response is sent back as a json object given below:
Handling the response
A successful response to this request contains the following fields:
Name | Description |
---|---|
access_token | The token that must be used to access the CORE APIs. |
expires_in | The remaining lifetime of the access token in seconds. The value always returned is 3600 seconds (one hour). Use the refresh token to get a fresh one |
token_type | Identifies the type of token returned. At this time, this field will always have the value 'bearer' |
id_token | Returned for openid and associated user scopes during authentication |