Table of Contents

Single Sign On

Single sign on is very easy to enable when using protocol agnostic authenticators. If the SAML IDP or OIDC OP you are trying to authenticate with has "allowSSO": "true" in their configuration, requests will automatically attempt Single sign on (SSO).

The way it works is completely opt-in for each authenticator. Each protocol agnostic authenticator (except AgnosticDispatcher, which will not SSO since it is always headless) has a configuration property called "setSSOParameters", which - if true- will set the SSO state for the relevant authenticator within the  SSO Group.

SSO Properties

An SSO state that gets saved when a protocol agnostic authenticator is executed successfully (and has "setSSOParameters": "true") will persist the following properties

  • The resulting item from the authenticator pipe (if any)
    • AgnosticAuthSelector is special here -- they will save the resulting item from the chosen / routed to-authenticator
  • The resulting user ID from the authentication
  • The authenticator ID responsible for the authentication

Multiple SSO states can be active at the same time (but just one state per authenticator) for each SSO Group (explained below).

SSO Flow & Criteria

When a request attempts SSO (set by "allowSSO" property at IDP / OP as described in the first paragraph), it will be treated as a normal authentication request until it lands at a protocol agnostic authenticator (AgnosticDispatcher will just route the request forward as usual). At this point, SSO will be allowed if the request is for the same SSO Group as previously, and an SSO State exists for this authenticator id. This means you are only allowed to skip an authenticator you have previously executed successfully. The resulting item from the previous authentication will be used to construct the response. This also means that SSO-enabled authenticators should not rely on in-data that can vary based on the login context (if it does, it should be directed elsewhere with a Dispatch), as the SSO state will just pick the same item as from the initial authentication, and proceed from there.

SSO Groups

SSO Groups allow an authentication session to be shared between entities. An entity in this context means a unique combination of protocol (SAML or OpenID Connect) and id (IdP ID or OP ID). By default, each entity is its own SSO Group. You can configure your SAML IdP or OIDC OP to belong to a specific SSO Group simply by adding the configuration parameter "ssoGroupId": "myvalue".

The purpose of this is to allow both SAML and OIDC authentication for the same authority. You simply configure your OIDC OP and SAML IdP to use the same authenticatorId and belong to the same SSO Group, and you can log into OIDC and then SSO into SAML, or vice versa. It is not recommended to add several entities of the same protocol into the same SSO Group, but it is possible.

SSO-enabled authenticators within a sequence

You may have SSO-enabled authenticators that you want to use within a sequence (e.g. for step-up authentication). For clarification on what a "sequence" is -- check the documentation for SequenceAuthenticator, also new in PAS 5.1. If you have an example sequence as such:

  1. DynamicAuthenticator (username & password) -- SSO ENABLED (setSSOParameters: true)
  2. AssignmentAuthenticator

Then executing the sequence will (if you have previously authenticated that particular authenticator successfully at this entity) SSO past the first step, and only perform the second step. This allows for powerful and easy-to-configure step-up authentication. See the example of how to configure step-up authentication for more details: Step-up authentication

Customizing your SSO behavior

You may have use cases where you need slightly different SSO behavior, for example if you want to direct your authentication flow based on properties from an initial authentication, you can use Meta Attributes. Meta attributes will allow you to set some attributes upon successful execution of an authenticator, which you can then use later in subsequent authentication flows.

For example, you may want to create a step-up flow where previously authenticated users of different roles are directed to different step-up authenticators. This can easily be achieved by setting a meta attribute for that role, and using a Dispatcher to direct the flow.

You may often want to use AgnosticAuthSelector as an SSO enabled authenticator. If you use the conditional options for a selector, SSO will only be available if the matching options for the current flow would allow for the same option that set the initial SSO. This creates a powerful configuration possibilities like the example below.

Level of Assurance-based SSO selector

In this example, the requested level-of-assurance (LoA) determines which authentication options are available. Note that the example methods in this scenario are not necessarily accurate representations of official LoA values.

If the requested LoA is 3, the only login methods available in this scenario are BankID and OneID. However, if LoA is 2 then a "Username, Password and SMS" option is also available. Furthermore for LoA 1, all methods are available, including basic username / password.

What this means in practice is that even though this authenticator is SSO-enabled, a user may only SSO if the selector returns login options matching what they are already authenticated with. For example, if a user first authenticates with username / password (LoA 1) and then tries to access another application requiring only LoA 1, it may SSO. However, if it were to try logging onto an application requiring LoA 2 or 3, it would be presented with the selector again where you may choose one of the available methods.

If the user instead authenticated itself with one of the LoA 3 methods (BankID or OneID) from the beginning, it would be able to SSO in any scenario, as those options are always available.

{
    "alias": "selector",
    "name": "AgnosticAuthSelector",
    "configuration": {
        "possibleAuthenticators": [
            {
                "authenticator": "oneID"
            },
            {
                "authenticator": "bankID"
            },
            {
                "authenticator": "usernamePasswordSms",
                "expression": "context.requestedAuthenticationContext.contains('http://id.elegnamnden.se/loa/1.0/loa1') || context.requestedAuthenticationContext.contains('http://id.elegnamnden.se/loa/1.0/loa2')"
            },
            {
                "authenticator": "usernamePassword",
                "expression": "context.requestedAuthenticationContext.contains('http://id.elegnamnden.se/loa/1.0/loa1')"
            },
        ],
        "setSSOParameters": "true"
    },
    "id": "<unique_id>"
}

Blocking SSO in certain scenarios

One capability of AgnosticDispatcher (technically also for AgnosticAuthSelector) is the forceAuth attribute. It will make all authenticators in that branch of the authentication tree unable to use SSO. For example, you can use this to directly block some applications from using SSO like in the example below. Both these options will route to the same SSO enabled selector, but one of them will disable SSO for that authentication.

{
    "alias": "dispatch",
    "name": "AgnosticDispatcher",
    "configuration": {
        "mapping": [
            {
                "authenticator": "selector",
                "forceAuth": "true",
                "useForRequestIssuers": ["SomeSAMLSPEntityId", "SomeOIDCRPClientId", "SomeInternalApp"]
            },
            {
                "authenticator": "selector",
                "expression": "true"
            },
        ],
        "setSSOParameters": "true"
    },
    "id": "<unique_id>"
}