Skip to main content
Skip table of contents

Protocol Fundamentals

SAML

Artifact Binding

Typically in SAML, the authentication request and assertion data is sent through the browser (http POST or http REDIRECT binding).

However, in some cases you may not want to expose the entire message to the browser.  In this case, the message contents are replaced by an artifact reference, that can be requested from the artifact endpoint (backchannel).

Both the Authentication Request and the Assertion can be sent using the Artifact binding.

Note: TrustBuilder.io (acting as Service Provider) currently only supports getting the Assertion via the artifact binding. 

Other use cases are not supported:

  • Acting as Service Provider: sending the Authentication Request with an Artifact Binding

  • Acting as Identity Provider: receiving the Authentication Request with an Artifact Binding 

  • Acting as Identity Provider: sending the Assertion with an Artifact Binding 

Security Considerations

Usage

There are no strong indications that the artifact binding is more or less secure than the post/redirect binding. Because artifact bindings add complexity and additional points of failure, it's not our recommended default approach for a SAML integration.

However there are several reasons why Artifact binding would be preferred:

  • Technical restrictions (eg. to reduce the size of the message)

  • Encryption is not practical or desirable (as this is more CPU intensive)

  • Reluctance to expose the message contents to the browser

Two-way SSL

Because we currently only support getting the assertion via the artifact binding, there is only a practical need for the IDP to present the artifact endpoint on a TLS secured endpoint.

Although the SAML specification does not mandate how to secure the Artifact binding, we suggest Two-SSL as a recommendation:

Example:

  1. The client (SP) should present its certificate to artifact resolution endpoint, to avoid unauthorized parties to access the Artifact Resolution Endpoint.

  2. The Identity Provider provides the artifact response, which is signed with its own certificate to prove the authenticity.

Additional measures may include that the artifact can only be resolved once, and that it remains available for only a limited amount of time (ie. several minutes).

IDP Push

An IDP Push is an Identity Provider initiated Single Sign-On. 

Where the normal authentication flow is initiated by an Authentication Request from the Service Provider, this is the opposite. The authentication starts by the Identity Provider, who provides an Assertion. 

The assertion may or may not contain a relayState or redirect_uri (the Service Provider to which the assertion is to be presented). 

When TrustBuilder.io receives an IDP-initiated assertion and it does not contain a relayState/redirect_uri and cannot be linked to an SP request, the user will be directed to the Application Catalog.

Endpoint

This is an endpoint that can be used to trigger an "IDP push" from TrustBuilder.io to a SAML Service Provider.

Endpoint:  GET idhub/authenticate/push

Parameters:

  • entityId (required)

  • relayState (optional)

  • authenticationContext (optional)

  • comparison (optional)

  • forceAuthentication (optional)

It is possible that the relayState parameter is used to indicate to the SAML SP what URL the user has to be redirected.

OAuth/OIDC

OpenIDConnect Error Codes

Error Code

Usage

"invalid_client"

  • When the client is not known

  • When the code grant is not enabled for the client

  • When in a code grant there is no user session

"invalid_request"

  • When the message fails to parse (e.g. required parameters missing)

  • When the redirection_uri is not allowed

  • When in "urn:ietf:params:oauth:grant-type:token-exchange" grant, the requested token type is not supported

"invalid_request_object"

  • When the request object is not valid

"unauthorized_client"

  • When the client is blocked

  • When a PUBLIC client requests the client credentials grant

  • When client credentials grant is not enabled for the client

  • When "password" grant is not enabled for the client

  • When "urn:ietf:params:oauth:grant-type:jwt-bearer" grant is not enable for the client

  • When "urn:ietf:params:oauth:grant-type:token-exchange" grant is not enabled for the client

  • When CONFIDENTIAL client authorization fails (client secret)

"unsupported_response_type"

  • When the response type is not allowed for the given client

"invalid_grant"

  • When a PUBLIC client does not provide a code challenge and method to the authorize endpoint

  • When a PUBLIC client fails to offer a valid code verifier to the token endpoint

  • When cross origin validation fails (Origin not in whitelist)

  • When the code offered to the token endpoint has expired

  • When the code offered to the token endpoint was revoked (possible double use)

  • When in "urn:ietf:params:oauth:grant-type:jwt-bearer" grant we do not trust the issuer of the token offered for exchange

  • When in "urn:ietf:params:oauth:grant-type:jwt-bearer" grant the token offered for exchange has expired

  • When in "urn:ietf:params:oauth:grant-type:jwt-bearer" grant the signature is invalid

  • When in "urn:ietf:params:oauth:grant-type:jwt-bearer" grant the token offered for exchange is not a valid JWT

  • When in "password" grant, the credentials are invalid

  • When "refresh_token" grant is not enabled for the client

  • When in "refresh_token" grant the refresh token has expired

  • When in "refresh_token" grant the refresh token was revoked

  • When in "refresh_token" grant the client is blocked

  • When in "urn:ietf:params:oauth:grant-type:token-exchange" grant, there is no existing consent of the subject for the client

  • When on the token introspection endpoint the token offered was not found for the client

"unsupported_grant_type"

  • When the grant_type is not supported

"invalid_scope"

  • When the scopes requested from the token endpoint are not covered by the offered code

  • When the scopes requested from the token endpoint are not covered by the offered refresh token

"access_denied"

  • When the user denies access to the client

"consent_required"

  • When user info endpoint is offered a token that has no user info attached (e.g. token from client credentials grant)

"invalid_token"

  • When user info endpoint is accessed without a valid bearer access token in the Authorization header

OAuth Token Exchange

The Token Exchange process is an extension on the OAuth 2.0 protocol, as described in the following draft specification: https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-19

It allows a Client to access multiple resources with a single access token, by exchanging it at TrustBuilder.io for access tokens that have, for instance, a reduced scope.  It has the following two major use cases:

  • Impersonation → A client is impersonating a principal, to gain access to its resources.  The impersonating client has all the rights of the principal it's impersonating.

  • Delegation → A principal is acting as a delegate of another principal to access its resources.  It retains its own rights, and the resource is aware that this client is acting on behalf of a different client.  
    This mode is currently not supported by TrustBuilder.io.

TrustBuilder.io can accept access tokens, or SAML assertions from any known IDP, and exchange them for an access token to a specific resource (issued by TrustBuilder). This can dramatically simplify the implementation on the side of the resource; as it only needs to integrate with a single IDP.  Which makes this a very useful implementation for a Microservices architecture, as an external access token can be exchanged for an internal token.

When to use Token Exchange?

There are scenarios when a Client accesses a resource server, which in turn needs to access resources hosted by other downstream services.

The Client sends in the access token that it received to TrustBuilder.io, which acts as a Security Token Service (STS). TrustBuilder.io will exchange the token provided by the Client with a token that can be used by the downstream service (Configured as an OAuth SP in TrustBuilder.io).  This new token may have a reduced scope or expiration timestamp.

This setup is particularly useful in an architecture where lots of independent services exist, which each have their own OAuth Client ID. It allows all business and authorization logic to be concentrated in a single entity, and a single access token issuer can be used throughout the service landscape, greatly improving user experience.

Flow

The following flowchart explains the internal logic TrustBuilder.io uses to validate a request under the Token Exchange grant.

  • Which IDP's are trusted? If the IDP is trusted, the token is validated based on the IDP's configuration (which must be set in TrustBuilder.io)

  • Has the user given consent?
    If the downstream service accesses information of the user which requires content, TrustBuilder.io will verify that this consent exists (for this combination of Scope, User and Service Provider).
    The token exchange will never request a user to grant consent, so the consent must already exist or be provided out of band.

  • Additional business logic via workflows

Using Token Exchange with a Workflow IDP

TrustBuilder.io workflows (i.e. Internal IDP's) can be used as Identity Providers for a Token Exchange grant, as long as they provide a token which can be validated.

The IDP workflow also requires support for validating one of its own dispensed tokens.

Understanding Scopes

Scopes provide a way to limit the amount of access that is granted to an access token.  

They are used both in OAuth2 and OpenIDConnect. However, OpenIDConnect extends the usage of scopes.

Authorization

Scopes can be authorized by a user. This is typically requested at the point the user logs in, as shown below. 

A scope is requested by a Service Provider. It is authorized by a user, who is authenticated by an Identity Provider.

Though not every request is necessarily authorized by a user (eg. in a machine-to-machine context).  But Scopes are still used in this case.

OAuth2 vs OpenIDConnect

OAuth2

You can implement your API's to enforce a restriction of a combination of scopes. So, when a client receives a token that has "READ" scope, and it uses this token to call an API endpoint that requires "WRITE" access, the call will fail.

OAuth scopes are defined as a list of names in the metadata.

OAuth scopes are applied on the API Service Providers in TrustBuilder.io.   There you define which scope(s) are allowed to access certain API locations and methods.

OpenIDConnect

OpenIDConnect in an extension to OAuth2, so the principles covered by OAuth2 still apply. But in addition, A Service Provider can request additional user information (=claims) from the IDP (provided in an ID Token, in addition to an Access Token).  

Pre-defined sets of Claims can be requested using specific scope values. Although not currently supported by TrustBuilder.io, individual Claims can also be requested using the claims request parameter.

A scope called 'openid' MUST be included in an Authorization request, to make it as an OpenIDConnect request.  Otherwise, the request will be made as an OAuth2 request.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.