JWT Authentication

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties. CAS provides support for token-based authentication on top of JWT, where an authentication request can be granted an SSO session based on a form of credentials that are JWTs.

Overview

CAS expects a token parameter to be passed along to the /login endpoint. The parameter value must be a JWT.

JCE Requirement

It's safe to make sure you have the proper JCE bundle installed in your Java environment that is used by CAS, specially if you need to use specific signing/encryption algorithms and methods. Be sure to pick the right version of the JCE for your Java version. Java versions can be detected via the java -version command.

CAS does not create JWTs. Here is an example of how to generate a JWT via Pac4j:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
final String signingSecret = RandomStringUtils.randomAlphanumeric(256);
final String encryptionSecret = RandomStringUtils.randomAlphanumeric(48);

System.out.println("signingSecret " + signingSecret);
System.out.println("encryptionSecret " + encryptionSecret);

final JwtGenerator<CommonProfile> g = new JwtGenerator<>();
g.setSignatureConfiguration(new SecretSignatureConfiguration(signingSecret, JWSAlgorithm.HS256));
g.setEncryptionConfiguration(new SecretEncryptionConfiguration(encryptionSecret, 
        JWEAlgorithm.DIR, EncryptionMethod.A192CBC_HS384));

final CommonProfile profile = new CommonProfile();
profile.setId("casuser");
final String token = g.generate(profile);
System.out.println("token: " + token);

Once the token is generated, you may pass it to the /login endpoint of CAS as such:

1
/cas/login?service=https://...&token=<TOKEN_VALUE>

Configuration

JWT authentication 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-token-webflow</artifactId>
     <version>${cas.version}</version>
</dependency>

Configure the appropriate service in your service registry to hold the secrets:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "https://.+",
  "name" : "testId",
  "id" : 1,
  "properties" : {
    "@class" : "java.util.HashMap",
    "jwtSigningSecret" : {
      "@class" : "org.apereo.cas.services.DefaultRegisteredServiceProperty",
      "values" : [ "java.util.HashSet", [ "<SECRET>" ] ]
    },
    "jwtEncryptionSecret" : {
      "@class" : "org.apereo.cas.services.DefaultRegisteredServiceProperty",
      "values" : [ "java.util.HashSet", [ "<SECRET>" ] ]
    },
    "jwtSigningSecretAlg" : {
      "@class" : "org.apereo.cas.services.DefaultRegisteredServiceProperty",
      "values" : [ "java.util.HashSet", [ "HS256" ] ]
    },
    "jwtEncryptionSecretAlg" : {
      "@class" : "org.apereo.cas.services.DefaultRegisteredServiceProperty",
      "values" : [ "java.util.HashSet", [ "dir" ] ]
    },
    "jwtEncryptionSecretMethod" : {
      "@class" : "org.apereo.cas.services.DefaultRegisteredServiceProperty",
      "values" : [ "java.util.HashSet", [ "A192CBC-HS384" ] ]
    }
  }
}

Note that the only required property is jwtSigningSecret.