Fork me on GitHub

CAS (v1.9)

pac4j allows you to login with a CAS server in various ways:

1) using the CAS login page (for a web site): when accessing a protected web site, the user will be redirected to the CAS login page to enter his credentials before being granted access to the web site

2) using proxy tickets (for a web service): if the user is already authenticated by CAS in the web application (use case 1), the web application can request a proxy ticket and use it to call the web service which is protected by CAS

3) using the CAS REST API (for a web service): a standalone / mobile application can call a web service by providing the CAS user credentials (these credentials will be directly checked via the CAS REST API).

It supports all CAS protocol versions (v1.0, v2.0 and v3.0).

The CAS server can also act as a SAML IdP, as an OpenID Connect provider or as an OpenID provider. In that case, you must not use the CAS support, but the appropriate SAML, OpenID Connect or OpenID supports.

0) Dependency

You need to use the following module: pac4j-cas.

Example (Maven dependency):

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-cas</artifactId>
    <version>${pac4j.version}</version>
</dependency>

1) CAS login page (web site)

a) Application configuration

To login with a CAS server, the indirect CasClient must be defined (and optionally a CasProxyReceptor to deal with proxies). Your web application protected by the CasClient will thus participate in the SSO.

Since pac4j v1.9.2, the CAS configuration must be defined in a CasConfiguration object instead of directly in the CasClient.

Example:

CasClient casClient = new CasClient(new CasConfiguration("https://mycasserver/login"));

The https://mycasserver/login url is the login url of your CAS server.

After a sucessful login with a CAS server, a CasProfile is returned.

The CasConfiguration can be built with the CAS login url and / or with the CAS prefix url (when different urls are required):

CasConfiguration config = new CasConfiguration();
config.setLoginUrl("https://casserverpac4j.herokuapp.com/login");
config.setPrefixUrl("http://internal-cas-url");

You can define the CAS protocol you want to support (CasProtocol.CAS30 by default):

config.setProtocol(CasProtocol.CAS20);

You can also set various parameters:

Method Usage
setEncoding(String) Define the encoding used for parsing the CAS responses
setRenew(boolean) Define if the renew parameter will be used
setGateway(boolean) Define if the gateway parameter will be used
setTimeTolerance(long) Define the time tolerance for the SAML ticket validation
setTicketValidator(TicketValidator) Define a specific TicketValidator
setCallbackUrlResolver(CallbackUrlResolver) Define a specific CallbackUrlResolver (by default, the CallbackUrlResolver of the CasClient is used)

b) CAS configuration

Assuming your callback url is http://localhost:8080/callback, the CAS server will be called via https://mycasserver/login?service=http://localhost:8080/callback?client_name=CasClient.

So you must define in the CAS services registry the appropriate CAS service matching this url: http://localhost:8080/callback?client_name=CasClient and with the appropriate configuration: which attributes to return? Does it support proxies?

Read the CAS documentation for that.

c) Proxy support

For proxy support, the CasProxyReceptor class must be used, defined on the same or new callback url (via the security configuration) and declared in the CasConfiguration:

CasProxyReceptor casProxy = new CasProxyReceptor(); 
config.setProxyReceptor(casProxy);
// config.setAcceptAnyProxy(false);
// config.setAllowedProxyChains(proxies);

In this case, a CasProxyProfile is returned after a successful authentication and it can be used to get proxy tickets for other CAS services:

CasProxyProfile casProxyProfile = (CasProxyProfile) casProfile;
String proxyTicket = casProxyProfile.getProxyTicketFor(anotherCasServiceUrl);

d) Logout configuration

To handle CAS logout requests, by default (J2E web context), the CasSingleSignOutHandler is defined: it must be used in conjonction with the J2E SingleSignOutHttpSessionListener and the renewSession flag must be disabled in the “callback filter” in that case.

In the web.xml file:

<listener>
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>

Though, a specific CasLogoutHandler can be specified in other frameworks.

e) In a stateless way

In fact, you can even login with the CAS login page using a direct DirectCasClient. No session will be created and thus no logout will be necessary.


2) Proxy tickets (web service)

If you want to call a web service from a web application using the CAS identity, the proxy mode must be used as explained above.

The generated proxy tickets must be sent to the web services and the web services must be properly protected by the direct DirectCasProxyClient. It requires a CasConfiguration.

Example:

CasConfiguration config = new CasConfiguration();
config.setLoginUrl("https://casserverpac4j.herokuapp.com/login");
config.setProtocol(CasProtocol.CAS30_PROXY);
DirectCasProxyClient directCasProxyClient = new DirectCasProxyClient(config, "http://localhost:8080/webservices");

After generating a proxy ticket (like PT-1), the web service will be called on a url similar to: http://localhost:8080/webservices/myoperation?ticket=PT-1.

The DirectCasProxyClient will validate the proxy ticket and the service url (defined in the constructor: http://localhost:8080/webservices) on the CAS server to get the identity of the user.

This requires to define the appropriate CAS service (matching the http://localhost:8080/webservices url) on the CAS server side.

This DirectCasProxyClient internally relies on the CasAuthenticator. See how to deal with performance issues.


3) CAS REST API (web service)

The CAS server can be called via a REST API if the feature is enabled.

The CasRestFormClient and CasRestBasicAuthClient are direct clients which can be used to interact with the REST API of a CAS server:

Example:

CasRestFormClient casRestClient = new CasRestFormClient("https://mycasserver/");

These direct clients internally rely on the CasRestAuthenticator. See how to deal with performance issues.

After a successful authentication via the CasRestBasicAuthClient / CasRestFormClient, a CasRestProfile will be created.

This profile has no attributes as it was built by validating the CAS credentials on the REST API. You must request a service ticket and validate it to get a CasProfile with attributes (as the default protocol used is CAS v3.0).

Indeed, with the CasRestProfile, you’ll be able to:

Notice that in previous versions, the CasRestProfile was named HttpTGTProfile and the TokenCredentials was replaced by CasCredentials.