OpenID Connect Authentication

Allow CAS to act as an OpenId Connect Provider (OP).

Remember

OpenId Connect is a continuation of the OAuth protocol with some additional variations. If you enable OpenId Connect, you will have automatically enabled OAuth as well. Options and behaviors that are documented for the OAuth protocol support may apply here just the same.

Support is enabled by including the following dependency in the WAR overlay:

1
2
3
4
5
<dependency>
  <groupId>org.apereo.cas</groupId>
  <artifactId>cas-server-support-oidc</artifactId>
  <version>${cas.version}</version>
</dependency>

To learn more about OpenId Connect, please review this guide.

The current implementation provides support for:

Endpoints

Field Description
/oidc/.well-known The discovery endpoint used to query for CAS OIDC configuration information and metadata.
/oidc/.well-known/openid-configuration Same as above.
/oidc/jwks Contains the server’s public signing keys, which clients may use to verify the digital signatures of access tokens and ID tokens issued by CAS.
/oidc/authorize Authorization requests are handled here.
/oidc/profile User profile requests are handled here.
/oidc/introspect Query CAS to detect the status of a given access token via introspection.
/oidc/accessToken, /oidc/token Produces authorized access tokens.
/oidc/revoke Revoke access or refresh tokens.
/oidc/register Register clients via the dynamic client registration protocol.

Register Clients

Clients can be registered with CAS in the following ways.

Statically

OpenID Connect clients can be statically registered with CAS as such:

1
2
3
4
5
6
7
8
{
  "@class" : "org.apereo.cas.services.OidcRegisteredService",
  "clientId": "client",
  "clientSecret": "secret",
  "serviceId" : "^<https://the-redirect-uri>",
  "name": "OIDC",
  "id": 1000
}

Note that OpenID connect clients as service definitions are an extension of OAuth services in CAS. All settings that apply to an OAuth service definition should equally apply here as well. The following fields are specifically available for OpenID connect services:

Field Description
clientId Required. The identifier for this client application.
clientSecret Required. The secret for this client application.
serviceId Required. The authorized redirect URI for this OIDC client.
implicit Optional. Whether the response produced for this service should be implicit.
supportedGrantTypes Optional. Collection of supported grant types for this service.
supportedResponseTypes Optional. Collection of supported response types for this service.
signIdToken Optional. Whether ID tokens should be signed. Default is true.
jwks Optional. Resource path to the keystore location that holds the keys for this application.
encryptIdToken Optional. Whether ID tokens should be encrypted. Default is false.
idTokenEncryptionAlg Optional. The algorithm header value used to encrypt the id token.
idTokenSigingAlg Optional. The algorithm header value used to sign the id token.
idTokenEncryptionEncoding Optional. The algorithm method header value used to encrypt the id token.
subjectType Optional value chosen from public or pairwise. Type to use when generating principal identifiers. Default is public.
sectoreIdentifierUri Optional. Host value of this URL is used as the sector identifier for the pairwise identifier calculation. If left undefined, the host value of the serviceId will be used instead.
Keep What You Need!

You are encouraged to only keep and maintain properties and settings needed for a particular integration. It is UNNECESSARY to grab a copy of all service fields and try to configure them yet again based on their default. While you may wish to keep a copy as a reference, this strategy would ultimately lead to poor upgrades increasing chances of breaking changes and a messy deployment at that.

Service definitions are typically managed and registered with CAS by the service management facility.

Usage Warning!

CAS today does not strictly enforce the collection of authorized supported response/grant types for backward compatibility reasons if left blank. This means that if left undefined, all grant and response types may be allowed by the service definition and related policies. Do please note that this behavior is subject to change in future releases and thus, it is strongly recommended that all authorized grant/response types for each profile be declared in the service definition immediately to avoid surprises in the future.

Dynamically

Client applications may dynamically be registered with CAS for authentication. By default, CAS operates in a PROTECTED mode where the registration endpoint requires user authentication. This behavior may be relaxed via CAS settings to allow CAS to operate in an OPEN mode.

Settings

To see the relevant list of CAS properties, please review this guide.

Server Configuration

Remember that OpenID Connect features of CAS require session affinity (and optionally session replication), as the authorization responses throughout the login flow are stored via server-backed session storage mechanisms. You will need to configure your deployment environment and load-balancers accordingly.

Sample Client Applications

Claims

OpenID connect claims are simply treated as normal CAS attributes that need to be resolved, mapped and released.

Scope-based Claims

You may chain various attribute release policies that authorize claim release based on specific scopes:

1
2
3
4
5
6
7
8
9
10
11
{
  "@class" : "org.apereo.cas.services.OidcRegisteredService",
  "clientId": "...",
  "clientSecret": "...",
  "serviceId" : "...",
  "name": "OIDC Test",
  "id": 10,
  "scopes" : [ "java.util.HashSet", 
    [ "profile", "email", "address", "phone", "offline_access", "displayName", "eduPerson" ]
  ]
}

Mapping Claims

Claims associated with a scope (i.e. given_name for profile) are fixed in the OpenID specification. In the event that custom arbitrary attributes should be mapped to claims, mappings can be defined in CAS settings to link a CAS-defined attribute to a fixed given scope. For instance, CAS configuration may allow the value of the attribute sys_given_name to be mapped and assigned to the claim given_name without having an impact on the attribute resolution configuration and all other CAS-enabled applications.

If mapping is not defined, by default CAS attributes are expected to match claim names.

To see the relevant list of CAS properties, please review this guide.

User-Defined Scopes

Note that in addition to standard system scopes, you may define your own custom scope with a number of attributes within. These such as displayName above, get bundled into a custom scope which can be used and requested by services and clients.

If you however wish to define your custom scopes as an extension of what OpenID Connect defines such that you may bundle attributes together, then you need to first register your scope, define its attribute bundle and then use it a given service definition such as eduPerson above. Such user-defined scopes are also able to override the definition of system scopes.

To see the relevant list of CAS properties, please review this guide.

Authentication Context Class

Support for authentication context class references is implemented in form of acr_values as part of the original authorization request, which is mostly taken into account by the multifactor authentication features of CAS. Once successful, acr and amr values are passed back to the relying party as part of the id token.

Pairwise Identifiers

When pairwise subject type is used, CAS will calculate a unique sub value for each sector identifier. This identifier should not be reversible by any party other than CAS and is somewhat akin to CAS generating persistent anonymous user identifiers. Each value provided to every relying party is different so as not to enable clients to correlate the user’s activities without permission.

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "@class" : "org.apereo.cas.services.OidcRegisteredService",
  "clientId": "client",
  "clientSecret": "secret",
  "serviceId" : "^<https://the-redirect-uri>",
  "usernameAttributeProvider" : {
    "@class" : "org.apereo.cas.services.PairwiseOidcRegisteredServiceUsernameAttributeProvider",
    "persistentIdGenerator" : {
      "@class" : "org.apereo.cas.authentication.principal.OidcPairwisePersistentIdGenerator",
      "salt" : "aGVsbG93b3JsZA=="
    }
  }
}

Keystores

Each registered application in CAS can contain its own keystore as a jwks resource. By default, a global keystore can be expected and defined via CAS properties. The format of the keystore file is similar to the following:

1
2
3
4
5
6
7
8
9
10
11
{
  "keys": [
    {
      "d": "...",
      "e": "AQAB",
      "n": "...",
      "kty": "RSA",
      "kid": "cas"
    }
  ]
}

CAS will attempt to auto-generate a keystore if it can’t find one, but if you wish to generate one manually, a JWKS can be generated using this tool or this tool.