keycloakgoogle-oauthcaspac4japereo

CAS 6.1 - State Parameter null with Pac4J


I have set up CAS with LDAP/AD and database, which works. Now I want to add Keycloak, but I get an exception, regarding the state.

Caused by: org.pac4j.core.exception.TechnicalException: State parameter is different from the one sent in authentication request. Session expired or possible threat of cross-site request forgery

For testing I added Google, but a similar problem occurs.

DEBUG [org.pac4j.oauth.credentials.extractor.OAuth20CredentialsExtractor] - <sessionState: null / stateParameter: Optional[TST-1-v1va-S-4rLb45kax1568WxwP5aX-q2X]>
INFO [org.pac4j.oauth.client.Google2Client] - <Failed to retrieve or validate credentials: State parameter mismatch: session expired or possible threat of cross-site request forgery>

I can see the successful auth with token for both keyloak/google in the logs, which means keycloak/google work in principle. The problem seams to be, that after redirecting back to CAS, the session has already ended. The sessionstore inside the context is empty. Therefore, the state is null and can not be matched to the TST. When I set withState = false in pac4j everything works, but I want to use state for security.

In this question in a pac4j google group, someone had the same problem, because he didn't use the standard port, which I did too. But changing to 80/443 didn't solve it for me. I am running in a tomcat 9 with a selfsigned ssl cert on localhost.

Any other suggestions?

Edit
I am almost certain, the problem comes with the external tomcat. But so far I have not found an working documentation on how to setup the external tomcat correctly. Open for suggestions.

Update
Seams like cas-server-support-oauth-webflow is breaking the pac4j webflow. If I remove this dependency, it works. Don't know if it's a bug or supposed to work that way. Without OAuth-Webflow I don't get access_token for Ldap/database.


Solution

  • I had the same problem and managed to handle it with v6.2.0-RC2 version of cas. After adding

    cas.authn.pac4j.replicateSessions=false
    

    into my etc/cas/config/cas.properties it fixed problem for me.

    From https://github.com/apereo/cas/blob/v6.2.0-RC2/docs/cas-server-documentation/configuration/Configuration-Properties.md#pac4j-delegated-authn:

    # cas.authn.pac4j.typedIdUsed=false
    # cas.authn.pac4j.principalAttributeId=
    # cas.authn.pac4j.name=
    # cas.authn.pac4j.order=
    # cas.authn.pac4j.lazyInit=true
    # cas.authn.pac4j.replicateSessions=true
    

    From https://github.com/apereo/cas/blob/v6.2.0-RC2/api/cas-server-core-api-configuration-model/src/main/java/org/apereo/cas/configuration/model/support/pac4j/Pac4jDelegatedAuthenticationProperties.java#L58:

     /**
     * Indicates whether profiles and other session data,
     * collected as part of pac4j flows and requests
     * that are kept by the container session, should be replicated
     * across the cluster using CAS and its own ticket registry.
     * Without this option, profile data and other related
     * pieces of information should be manually replicated
     * via means and libraries outside of CAS.
     */
     private boolean replicateSessions = true;
    

    Warning - Default value for this property is true and changing to false is not recommented for clusters.