Calling a secured API from a server using OAuth 2.0 Token Exchange.
This flow is used in scenarios where a server needs to make secured calls to an API without user interaction (B2B scenario). It can only be used by confidential clients who are in possesion of an access token obtained from the ACM/IDM STS for the Authorization Server.
The way to get a secure access token from acm/idm:
- The client application uses the openid authorization code flow to obtain a user-specific access token
For more information on requesting tokens please refer to the documentation on the Openid connect
This flow is initiated by a server which sends an HTTP POST request for an access token to the Digitaal Vlaanderen Authorization Server. In the request the server provides the client credentials, the requested scopes and a valid subject_token en subject_tokentype to exchange for an access token. The response will contain the access token and the scopes granted to the client.
Exchanging the subject_token for an access token.
The endpoint used to exchange a subject_token for an access token is https://oauth.vlaanderen.be/authorization/ws/oauth/v2/token/Endpoint | Description | Method |
---|---|---|
https://oauth.vlaanderen.be/authorization/ws/oauth/v2/token/ | This endpoint is the target of the initial request to exchange a subject_token for an access token. | HTTP-POST |
The body is composed of the following parameters.
Parameter | Values | Description | Required |
---|---|---|---|
grant_type |
urn:ietf:params:oauth:grant-type:token-exchange | Value MUST be set to "urn:ietf:params:oauth:grant-type:token-exchange". | Yes |
resource |
Indicates the location of the target service or resource where the client intends to use the requested securitytoken. | Optional value for example https://backend.example.com/api | No |
subject_token |
Access token received from ACM/IDM f.e. accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC | A security token that represents the identity of the party on behalf of whom the request is being made. | Yes |
subject_token_type |
Accesstoken: urn:ietf:params:oauth:token-type:access_token or Identitytoken: urn:ietf:params:oauth:token-type:id_token (Identitytoken not yet implemented) |
An identifier, that indicates the type of the security token in the "subject_token" parameter. | Yes |
actor_token |
Geosecure access token. | A security token that represents the identity of the acting party. Typically, this will be the party that is authorized to use the requested security token and act on behalf of the subject. | Yes |
actor_token_type |
Accesstoken: urn:ietf:params:oauth:token-type:access_token | An identifier, that indicates the type of the security token in the "actor_token" parameter. | Yes |
scope |
Space delimited set of scopes the client requests. | One or more of the scope values available for the specified client. See the OAuth administration site for available scopes. Multiple scopes must be space seperated. | Yes |
Client Authentication
You also need to authenticate the client for this call, you can find information in client authentication
The client authentication methods that are allowed are:
- With a JSON Web Key
- With the client identifier and client secret in the header
- With the client identifier and client secret in the body
If you use a JSON Web Token the audience for this call in the JWT token must be:
-
https://oauth.vlaanderen.be/authorization/ws/oauth/v2/token
Examples
POST https://oauth.vlaanderen.be/authorization/ws/oauth/v2/token/ HTTP/1.1
Host: oauth.vlaanderen.be
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&resource=https%3A%2F%2Fbackend.example.com%2Fapi%20
&subject_token=accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
&subject_token_type=
urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
&scope=MapRequest
&client_id=789456
&client_secret=298MSGHSJY93273253GIDGIDZN_VCX2H3%3D%3D
POST https://oauth.vlaanderen.be/authorization/ws/oauth/v2/token/ HTTP/1.1
Host: oauth.vlaanderen.be
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&resource=https%3A%2F%2Fbackend.example.com%2Fapi%20
&subject_token=accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
&subject_token_type=
urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
&scope=MapRequest
&client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imo5c1ZrNU9INVlOQS1uMS00bDdUM013UVJJUSJ9.eyJzdWIiOiI3ODk0NTYiLCJpc3MiOiI3ODk0NTYiLCJleHAiOiIxNTE2MjQwMDIyIiwiaWF0IjoiMTU1MjkwOTYwMSIsImp0aSI6IjYzMjMzY2Q5LTIxYjgtNGZhMS04ODU4LTY2YjcxNWY3YTg2NiIsImF1ZCI6Imh0dHBzOi8vb2F1dGgudmxhYW5kZXJlbi5iZS9hdXRob3JpemF0aW9uL3dzL29hdXRoL3YyL2F1dGhvcml6YXRpb24ifQ.dPWB45Fe-ctNq5Q5bwGSVfFjbVoGMd6mrKzd3V9Xaq136vnAABYstr9v0E-rTz_VjoHJOpS23336-3ooDEl-bahfVJhpsjTW2_8X8eU9Jdyznl5VWpLKfAmHW9ycWupMf3jeCGfbLe5e1Nj1AmMuvufwawpb8-c9XuRoJoK6y232gRa-xfBQxJMcaS8L9qxYVLecPeqQjnjAs0qDOzrRzyIDLC9fBUG0UeC4sd_rEMSgBSj_N5uMbg4hyV6HB6-WuJy0R_MWFRq_fgqa3vRqDd9D0epLc-_QugfeGgdryKer57WLtbYfDXWoXEgsKmqToHyZx2G96ohuIqws3ytxxg
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
POST https://oauth.vlaanderen.be/authorization/ws/oauth/v2/token/ HTTP/1.1
Host: oauth.vlaanderen.be
Authorization: Basic Nzg5NDU2OjI5OE1TR0hTSlk5MzI3MzI1M0dJREdJRFpOX1ZDWDJIJTNEJTNE
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&resource=https%3A%2F%2Fbackend.example.com%2Fapi%20
&subject_token=accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
&subject_token_type=
urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
&scope=MapRequest
The body only contains extra newlines for readability. Be sure to urlencode the assertion, clientsecret, clientassertion, clientassertion type and redirect uri.
Handling the response
The OAuth 2.0 Authorization Server returns an access token to the client if it succesfully authenticates the client, and the authorization code and redirect uri are valid. The body of the response is a JSON result.Property | Values | Description |
---|---|---|
access_token |
A string representing the access token issued by the OAuth 2.0 Authorization Server | The access token issued by the OAuth 2.0 Authorization Server |
token_type |
bearer | The access token is a bearer token. |
expires_in |
A numeric value | The lifetime of the access token in seconds starting from the time the token was issued. The lifetime of the access token is always 1 hour (3600s). |
scope |
Space delimited set of scopes the resource owner granted the client. | The scopes specified can be different from the requested scopes when the resource owner doesn't or can't grant all of the requested scopes. |
Example
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"MOB1ZkyrqdSay4-xm39Z6A==",
"token_type":"bearer",
"expires_in":3600
}
Handling an error
The OAuth 2.0 Authorization Server returns an error as a JSON result to the client if the request parameters are not correct or an access token could not be issued.Property | Value | Description |
---|---|---|
error |
access_denied |
The resource owner or the OAuth 2.0 Authorization Server denied the request. |
unsupported_grant_type |
The OAuth 2.0 Authorization Server does not support obtaining an access token of the specified grant type using this method. | |
invalid_grant |
The provided authorization code, refresh token or assertion is invalid, revoked expired, or the redirect uri used, was not the redirect uri used in the initial authorization request. | |
invalid_scope |
The requested scope is invalid, unknown, or malformed. | |
unauthorized_client |
The client is not authorized to request an access token using this method. | |
invalid_request |
The request is missing required parameters or is malformed. | |
error_description |
Descriptive text to provide additional information about the error. |
Example
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"error":"invalid_request"
}
Calling an API
When your application has received an access token, you can access an API by including the access token in the Authorization HTTP Header using the Bearer scheme.
For example a call to an API using the access_token Authorization: Bearer HTTP header looks as follows:
GET https://api.vlaanderen.be/ws/klip/v1/maprequest HTTP/1.1
Authorization: Bearer LTgaAik7F-smmQ65_nVfag==
Host: api.agiv.be
When HTTP Header operations are not possible, for example when using the url in an image src attribute, the access token can be incuded as a query string parameter.
For example, a call to the API using the access_token query string parameter looks like the following:
GET https://api.vlaanderen.be/ws/klip/v1/maprequest?access_token=LTgaAik7F-smmQ65_nVfag== HTTP/1.1