Calling a secured API from a server using a SAML 1.1 Assertion.
This flow is used in scenario's 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 a client secret and obtained a SAML1.1 or SAML2.0 assertion from the Digitaal Vlaanderen STS for the Authorization Server or obtained an assertion from their own IP-STS or IdP if they are trusted by the Digitaal Vlaanderen STS.
There are two ways to obtain a valid SAML token:
- A SAML token is requested from the Digitaal Vlaanderen STS for the Authorization Server using the realm: urn:agiv.be/oauth
- A SAML token is requested from the clients IP-STS or IdP for the Digitaal Vlaanderen STS using the realm urn:agiv.be/sts for production and urn:informatievlaanderen.be/sts/beta for external test.
For more information on requesting tokens please refer to the documentation on the STS framework Digitaal Vlaanderen
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 SAML assertion to exchange for an access token. The response will contain the access token and the scopes granted to the client.
Exchanging the SAML assertion for an access token.
The endpoint used to exchange a SAML assertion 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 SAML assertion 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:saml11-bearer or urn:ietf:params:oauth:grant-type:saml2-bearer | Value MUST be set to "urn:ietf:params:oauth:grant-type:saml11-bearer" or "urn:ietf:params:oauth:grant-type:saml2-bearer". | Yes |
assertion |
The SAML 1.1 or SAML 2.0 XML assertion as Base64Url | Value MUST be Base64Url encoded following the specifications in http://tools.ietf.org/html/rfc4648#section-5 | 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. | No (if a default scope is defined for the specified client, otherwise 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%3Asaml11-bearer
&assertion=5fFiTSTWXCQwGx6lSmJHQ... [omitted for brevity] ... CQwGx6lS
&scope=MapRequest
&client_id=789456
&client_secret=298MSGHSJY93273253GIDGIDZN_VCX2H3
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%3Asaml11-bearer
&assertion=5fFiTSTWXCQwGx6lSmJHQ... [omitted for brevity] ... CQwGx6lS
&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%3Asaml11-bearer
&assertion=5fFiTSTWXCQwGx6lSmJHQ... [omitted for brevity] ... CQwGx6lS
&scope=MapRequest
The body only contains extra newlines for readability. Be sure to urlencode the assertion, clientsecret, clientassertion, client assertion type.
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