If your Apereo CAS deployment is configured to act as an OpenID Connect provider, then you will need to be careful with how you define the required issuer setting. In this blog post, we will examine the range of options available to define and tune the issuer value for Apereo CAS acting as an OpenID Connect provider.
Our starting position is based on the following:
7.1.x
21
An issuer identifier, in OpenID Connect terms, is a case-sensitive URL using the https
scheme that contains scheme, host, and optionally, port number and path components and no query or fragment components. This URL uniquely identifies the CAS server instance as an OpenID Connect provider and is a point for resolving important metadata about the server, such as its endpoints and capabilities.
When Apereo CAS is configured as an OpenID Connect provider, this issuer is defined in the CAS configuration as:
cas.authn.oidc.core.issuer=https://sso.example.org/cas/oidc
A client application need not know the issuer beforehand, since this setting can be determined dynamically using dynamic discovery. OpenID Connect defines a discovery mechanism, called OpenID Connect Discovery, which allows the CAS server to publish its metadata, including its issuer, at a well-known URL which typically is:
https://sso.example.org/.well-known/openid-configuration
This URL returns a JSON listing of the various endpoints, supported scopes and claims, public keys used to sign the tokens, and other details. The clients can use this information to construct a request to the CAS server.
{
"issuer": "https://sso.example.org/cas/oidc",
}
The issuer value is also put into issued ID tokens under the iss
claim. The specification indicates that the issuer identifier for the CAS OpenID Connect provider (which is typically obtained during Discovery) MUST exactly match the value of the iss
(issuer) claim. Given our previous examples, the iss
claim would always be https://sso.example.org/cas/oidc
.
In very extreme and special circumstances, you may decide to override the iss
claim to handle a particularly-weird integration for an OpenID Connect relying party. CAS provides an option to override the issuer for a given client application:
{
"@class": "org.apereo.cas.services.OidcRegisteredService",
"clientId": "client",
"clientSecret": "client",
"serviceId": "^http://localhost:8080.*",
"name": "OIDC",
"id": 1,
"scopes" : [ "java.util.HashSet", [ "profile", "openid" ] ],
"idTokenIssuer": "https://sso.example.org/custom/issuer"
}
The CAS adopter is also given the option to configure issuer aliases in form of regular expression patterns. An issuer alias,
Defines the regular expression pattern that is matched against the calculated issuer from the request. If the issuer that is extracted from the request does not match the issuer defined in the CAS configuration, this pattern acts as a secondary level rule to allow incoming requests to pass through if the match is successful.
Issuer aliases allow CAS to migrate easily from one issuer URL to another. You also have the means to identify the CAS OpenID Connect server by multiple issuer URLs.
As an example, suppose that your CAS server running on localhost:8443
defines the following issue:
cas.authn.oidc.core.issuer=https://sso.example.org/cas/oidc
The following request will produce an error if you decide to send a request to the JWKS endpoint:
> curl https://localhost:8443/cas/oidc/jwks
{"error":"invalid_request","error_description":"Invalid issuer"}
This, however, will produce the expected response:
> curl https://sso.example.org/cas/oidc/jwks
{"keys": [...]}
Let’s define our issuer alias pattern to support requests from localhost
:
cas.authn.oidc.core.accepted-issuers-pattern=https:\/\/localhost:8443.*
Now, this request should also produce the expected response:
> curl https://localhost:8443/cas/oidc/jwks
{"keys": [...]}
You can certainly control the issuer calculation and validation logic yourself by supplying the following bean in your CAS configuration:
@Bean
public OidcIssuerService oidcIssuerService() {
return new MyOidcIssuerService();
}
If you have questions about the contents and the topic of this blog post, or if you need additional guidance and support, feel free to send us a note and ask about consulting and support services.
I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please feel free to engage and contribute as best as you can.
Monday-Friday
9am-6pm, Central European Time
7am-1pm, U.S. Eastern Time
Monday-Friday
9am-6pm, Central European Time