Issue with LPPE and memcached ticket registry

127 views
Skip to first unread message

Windham, Gary D - (windhamg)

unread,
Apr 28, 2019, 9:28:12 PM4/28/19
to cas-...@apereo.org
Hi all,

I've been building/testing CAS v6.1.0 (HEAD), and was getting along fairly well until I ran into an error with LPPE and the memcached ticket registry I'm using.

I am using 389 Directory server for LDAP authentication and have password policy configured as follows:

# LDAP Password Policy Enforcement (LPPE) parameters
cas.authn.ldap[0].passwordPolicy.type=GENERIC
cas.authn.ldap[0].passwordPolicy.enabled=true
cas.authn.ldap[0].passwordPolicy.policyAttributes.accountLocked=javax.security.auth.login.AccountLockedException
cas.authn.ldap[0].passwordPolicy.loginFailures=6
cas.authn.ldap[0].passwordPolicy.warningAttributeValue=
cas.authn.ldap[0].passwordPolicy.warningAttributeName=
cas.authn.ldap[0].passwordPolicy.displayWarningOnMatch=true
cas.authn.ldap[0].passwordPolicy.warnAll=true
cas.authn.ldap[0].passwordPolicy.warningDays=30
cas.authn.ldap[0].passwordPolicy.accountStateHandlingEnabled=true
cas.authn.ldap[0].passwordPolicy.strategy=DEFAULT

I am using memcached (with AWS Elasticache support) and am using all of the defaults (just setting cas.ticket.registry.memcached.servers to the configuration endpoint node).

When I disable LPPE, everything works as expected--I can login, get a TGC, ST validation works, etc). When I enable LPPE and set my password expiration date to a threshold within 30 days, I get the expected "your password is about to expire" page, with the green "Continue" button. When I click that, I'm redirected to the CAS login page and the following errors appear in the log:

2019-04-29 01:10:22,684 ERROR [org.apereo.cas.ticket.registry.MemcachedTicketRegistry] - <Failed adding [TGT-1-*****ems91rmrGY-a1ab3d9633df]>
com.esotericsoftware.kryo.KryoException: com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: Class is not registered: org.apereo.cas.authentication.support.password.PasswordExpiringWarningMessageDescriptor
Note: To register this class use: kryo.register(org.apereo.cas.authentication.support.password.PasswordExpiringWarningMessageDescriptor.class);

<...followed by big stack trace...>

Is there something I'm overlooking, or failed to add, in my config? Any pointers appreciated!

Thanks,
--Gary

--

Gary Windham

Principal Enterprise Systems Architect

University Information Technology Services 

The University of Arizona

 

Email: wind...@email.arizona.edu

Office: +1 520 626 5981

Doug Campbell

unread,
Apr 28, 2019, 10:36:36 PM4/28/19
to cas-...@apereo.org

Gary,

 

I don’t have an answer but I saw this same error yesterday when I was testing proxy authentication on my CAS 6.0.3 test setup.  In my case I haven’t configured LPPE.  I did try disabling it just now but that seemed to have no effect as the error still occurs.  In my case I am using spymemcache and not AWS Elasticache.  For now I have switched back to the default InMemory ticket registry and proxy authentication works fine with that.

 

If I figured out anything I will let you know and if you discover a solution please do report back.

 

Thanks!

--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CABpeFHGDx0-TPBmE-tMCmpfcgvr1eSUMhQF0xygfka%3DxXxzKVA%40mail.gmail.com.

Doug Campbell

unread,
Apr 28, 2019, 11:26:21 PM4/28/19
to cas-...@apereo.org

I don’t know if this is an ideal workaround but I found in my case if I changed the transcoder setting from KYRO to SERIAL that everything starting working great.

 

cas.ticket.registry.memcached.transcoder: SERIAL

 

In the documentation it recommends using KYRO stating “This component is recommended over the default Java serialization mechanism since it produces much more compact data, which benefits both storage requirements and throughput.”  There are two other options as well:  WHALIN and WHALINV1.

 

I am not sure if it really matters which one but since the use of KYRO seems buggy maybe the recommendation for using it is no longer the best.

Windham, Gary D - (windhamg)

unread,
Apr 29, 2019, 3:00:20 PM4/29/19
to cas-...@apereo.org
Doug, thank you very much for your feedback and the workaround. That does, indeed, fix the immediate issue at hand. Hopefully the Kryo serialization issue will be resolved soon.

Thanks again!
--Gary

--

Gary Windham

Principal Enterprise Systems Architect

University Information Technology Services 

The University of Arizona

 

Email: wind...@email.arizona.edu

Office: +1 520 626 5981



On Sun, Apr 28, 2019 at 8:26 PM Doug Campbell <wdouglas...@gmail.com> wrote:

I don’t know if this is an ideal workaround but I found in my case if I changed the transcoder setting from KYRO to SERIAL that everything starting working great.

 

cas.ticket.registry.memcached.transcoder: SERIAL

 

In the documentation it recommends using KYRO stating “This component is recommended over the default Java serialization mechanism since it produces much more compact data, which benefits both storage requirements and throughput.”  There are two other options as well:  WHALIN and WHALINV1.

 

I am not sure if it really matters which one but since the use of KYRO seems buggy maybe the recommendation for using it is no longer the best.

 

 

From: cas-...@apereo.org [mailto:cas-...@apereo.org] On Behalf Of Doug Campbell


Sent: Monday, April 29, 2019 10:36 AM
To: cas-...@apereo.org

--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.

Julien Gribonvald

unread,
Apr 30, 2019, 5:46:56 AM4/30/19
to cas-...@apereo.org

Hi,

To fix your problem you have to register the missing class, here is a PR to get as example to register some missing class  https://github.com/apereo/cas/pull/3857/files. So you can contribute ?

After my point of view is that's a problem that KRYO need to register all class to serialize them, but it doesn't seem to have an other way. After there is a good beneit to use KRYO as his serialization is more efficient than the default one.

Thanks,

Julien

Doug Campbell

unread,
May 1, 2019, 5:09:42 AM5/1/19
to cas-...@apereo.org

Thanks Julien.

 

I think I understand what is needed to be done for registering the missing class but I have no idea how to deploy a change to test it.  I’m using the cas-webapp-docker to deploy to Docker using cas-overlay-template.  If were able to give me some pointers as to how to test these changes I would go ahead and try to make this work on the 6.0.x branch.

 

Doug

Ray Bon

unread,
May 1, 2019, 3:26:34 PM5/1/19
to cas-...@apereo.org
Doug,

I have not used docker image but suspect it operate the same way as a stand alone deploy.
You create your package/class(es) in src/main/java (in root of project directory). It will get built and placed in the war.
https://apereo.github.io/cas/5.3.x/installation/Maven-Overlay-Installation.html

Ray
-- 
Ray Bon
Programmer Analyst
Development Services, University Systems

Julien Gribonvald

unread,
May 2, 2019, 4:51:15 AM5/2/19
to cas-...@apereo.org

Ray I'm not sure that will work with the cas-overlay-template done with gradle.

On my side I cloned the CAS repository following the documentation and I publish to my nexus, but with docker :

- clone the cas project and apply change and publish them to your git repo

- clone this git repo on your docker file and run commands like locally following the doc, inside the module you will have to build and install locally the change (command example to build this kind of module and to install it locally : ../../gradlew clean build install --configure-on-demand --build-cache --parallel -x test -x javadoc -x check --stacktrace -DskipNestedConfigMetadataGen=true -DskipGradleLint=true), like that your cas build from the cas-overlay-template will be able to use your change.

Julien

Doug Campbell

unread,
May 2, 2019, 12:06:29 PM5/2/19
to cas-...@apereo.org

Thanks guys this got me on the right track.

 

I first tried what Ray suggested but was having difficulties.  I then adjusted and tried Julien’s approach and saw success once I downgraded my Java version.  I then went back and tried Ray’s suggestion and was successful except that I had to put the files in the src/main/resources directory not src/main/java.

 

Anyway, I think I am starting to understand this though I want to write myself some step-by-step instructions and will probably go ahead and post those back.

 

Appreciate your help!

Doug Campbell

unread,
May 2, 2019, 12:20:26 PM5/2/19
to cas-...@apereo.org

Correction.  I think I had things cached.  It doesn’t work to put the files in src/main/resources.

Ray Bon

unread,
May 2, 2019, 12:39:39 PM5/2/19
to cas-...@apereo.org
Doug,

What is the file(s) that you want to modify?
src/main/java is for files that get compiled (.java).
src/main/resources is for everything else (images, .html, etc).

You will need to use jdk 11 for CAS 6.x.

Ray

Doug Campbell

unread,
May 2, 2019, 12:53:19 PM5/2/19
to cas-...@apereo.org

Ray,

 

I want to modify cas/support/cas-server-support-memcached-core/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java.

 

Doug

Ray Bon

unread,
May 2, 2019, 1:08:32 PM5/2/19
to cas-...@apereo.org
Doug,

OK, create the path src/main/java/org/apereo/cas/memcached/kryo/ and copy in CloseableKryoFactory.java (from apero/cas source).
You may need to modify build.gradle to include appropriate dependencies (as compile).

Get the project to build (no need to deploy) before making changes to CloseableKryoFactory.

Ray

Doug Campbell

unread,
May 2, 2019, 2:02:24 PM5/2/19
to cas-...@apereo.org

Ray,

 

That got me a little further along but when I try to build (./gradlew clean build) I get a lot of errors.  I have tried adding compile dependencies which has reduce the number of errors but now I am stuck.

 

This is what I am seeing in terms of errors:

 

> Task :compileJava FAILED

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:147: error: incompatible types: CloseableKryo cannot be converted to val

        val kryo = new CloseableKryo(this.kryoPool);

                   ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:148: error: cannot find symbol

        kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));

                                             ^

  symbol:   class DefaultInstantiatorStrategy

  location: class Kryo

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:149: error: cannot find symbol

        kryo.setWarnUnregisteredClasses(this.warnUnregisteredClasses);

            ^

  symbol:   method setWarnUnregisteredClasses(boolean)

  location: variable kryo of type val

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:150: error: cannot find symbol

        kryo.setAutoReset(this.autoReset);

            ^

  symbol:   method setAutoReset(boolean)

  location: variable kryo of type val

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:151: error: cannot find symbol

        kryo.setReferences(this.replaceObjectsByReferences);

            ^

  symbol:   method setReferences(boolean)

  location: variable kryo of type val

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:152: error: cannot find symbol

        kryo.setRegistrationRequired(this.registrationRequired);

            ^

  symbol:   method setRegistrationRequired(boolean)

  location: variable kryo of type val

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:154: error: cannot find symbol

        LOGGER.debug("Constructing a kryo instance with the following settings:");

        ^

  symbol:   variable LOGGER

  location: class CloseableKryoFactory

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:155: error: cannot find symbol

        LOGGER.debug("warnUnregisteredClasses: [{}]", this.warnUnregisteredClasses);

        ^

  symbol:   variable LOGGER

  location: class CloseableKryoFactory

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:156: error: cannot find symbol

        LOGGER.debug("autoReset: [{}]", this.autoReset);

        ^

  symbol:   variable LOGGER

  location: class CloseableKryoFactory

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:157: error: cannot find symbol

        LOGGER.debug("replaceObjectsByReferences: [{}]", this.replaceObjectsByReferences);

        ^

  symbol:   variable LOGGER

  location: class CloseableKryoFactory

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:158: error: cannot find symbol

        LOGGER.debug("registrationRequired: [{}]", this.registrationRequired);

        ^

  symbol:   variable LOGGER

  location: class CloseableKryoFactory

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:160: error: incompatible types: val cannot be converted to Kryo

        registerCasAuthenticationWithKryo(kryo);

                                          ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:161: error: incompatible types: val cannot be converted to Kryo

        registerExpirationPoliciesWithKryo(kryo);

                                           ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:162: error: incompatible types: val cannot be converted to Kryo

        registerCasTicketsWithKryo(kryo);

                                   ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:163: error: incompatible types: val cannot be converted to Kryo

        registerNativeJdkComponentsWithKryo(kryo);

                                            ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:164: error: incompatible types: val cannot be converted to Kryo

        registerCasServicesWithKryo(kryo);

                                    ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:165: error: incompatible types: val cannot be converted to Kryo

        registerImmutableOrEmptyCollectionsWithKryo(kryo);

                                                    ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:167: error: cannot find symbol

            LOGGER.trace("Registering serializable class [{}] with Kryo", c.getName());

            ^

  symbol:   variable LOGGER

  location: class CloseableKryoFactory

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:168: error: cannot find symbol

            kryo.register(c);

                ^

  symbol:   method register(Class)

  location: variable kryo of type val

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:170: error: incompatible types: val cannot be converted to Kryo

        return kryo;

               ^

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:174: error: cannot find symbol

        LOGGER.debug("Registering immutable/empty collections with Kryo");

        ^

  symbol:   variable LOGGER

  location: class CloseableKryoFactory

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:187: error: incompatible types: no instance(s) of type variable(s) T exist so that Set<T> conforms to val

        val singletonSet = Collections.singleton("key");

                                                ^

  where T is a type-variable:

    T extends Object declared in method <T>singleton(T)

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:190: error: incompatible types: no instance(s) of type variable(s) K,V exist so that Map<K,V> conforms to val

        val singletonMap = Collections.singletonMap("key", "value");

                                                   ^

  where K,V are type-variables:

    K extends Object declared in method <K,V>singletonMap(K,V)

    V extends Object declared in method <K,V>singletonMap(K,V)

/cas-overlay/src/main/java/org/apereo/cas/memcached/kryo/CloseableKryoFactory.java:193: error: incompatible types: no instance(s) of type variable(s) T exist so that List<T> conforms to val

        val list = Arrays.asList("key");

                                ^

  where T is a type-variable:

    T extends Object declared in method <T>asList(T...)

Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output

24 errors

Ray Bon

unread,
May 2, 2019, 2:14:01 PM5/2/19
to cas-...@apereo.org
val is part of lombok. Try adding this to build.gradle

    compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.2'

Ray

Doug Campbell

unread,
May 2, 2019, 2:21:30 PM5/2/19
to cas-...@apereo.org

Ray,

 

That didn’t seem to change anything.  Here is what I have added in the dependencies section of build.gradle:

 

compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.2'

compile "com.esotericsoftware:kryo:4.0.2"

compile group: 'com.esotericsoftware', name: 'kryo-shaded', version: '4.0.2'

compile group: 'de.javakaffee', name: 'kryo-serializers', version: '0.42'

compile "org.apereo.cas:cas-server-core-authentication-api:${casServerVersion}"

compile "org.apereo.cas:cas-server-core-authentication-attributes:${casServerVersion}"

compile "org.apereo.cas:cas-server-core-services-authentication:${casServerVersion}"

compile "org.apereo.cas:cas-server-core-services-api:${casServerVersion}"

compile "org.apereo.cas:cas-server-core-tickets-api:${casServerVersion}"

compile "org.apereo.cas:cas-server-core-util-api:${casServerVersion}"

compile "org.apereo.cas:cas-server-support-memcached-core:${casServerVersion}"

 

I came up with this based on looking at the error messages I saw and guessing what packages were needed.

Ray Bon

unread,
May 2, 2019, 4:37:57 PM5/2/19
to cas-...@apereo.org
Hmm, this is confusing.
I added it to my overlay, probably for the errors you are seeing. But I do not see a reference to projectlombok in cas master branch (or 6.0.x).
Some IDEs have lombok plugins but that should not be necessary for command line build.

Perhaps there is someone with more experience with lombok on the list.

Ray

Doug Campbell

unread,
May 3, 2019, 5:39:22 AM5/3/19
to cas-...@apereo.org

Okay.  I finally figured it out this time J  This is actually tested and confirmed to work.

 

Here are the steps:

1.      Create the directory structure src/main/java under the cas-overlay directory.

2.      Further create the directory structure of your project under src/main/java.

In my case since I was working on the CloseableKryoFactory.java file of the cas-server-support-memcache-core module code I created the same directory structure as in the apereo cas source code under src/main/java which is org/apereo/cas/memcached/kryo.

3.      Add the files that you are changing into their appropriate places in the directory structure under src/main/java.

In my case I added CloseableKryoFactory.java under src/main/java/org/apereo/cas/memcached/kryo.

4.      Make necessary changes to file(s).

5.      Now in order to build you need to add at least the gradle-lombox plugin to the dependencies.

 

This is done by modifying build.gradle with the highlighted lines:

 

buildscript {

    dependencies {

        classpath "io.franzbecker:gradle-lombok:$gradleLombokVersion"

    }

}

 

apply plugin: "io.franzbecker.gradle-lombok"

 

lombok {

        version = "$lombokVersion"

}

 

Note:     The version used for gradle-lombok and lombok can be obtained from the gradle.properties file in the apereo cas source root directory.

 

6.      In addition to this change in the build.gradle, it was also necessary to provide the lombok.config file from the apereo cas source root directory and put it in the cas-overlay directory.

7.      Then you will also need to add any other dependencies to the build.gradle file.  You should add these using compileOnly since they are already provided.  In the case of the changes I was making I figured out through trial and error that I needed the following dependencies (not sure if there is a faster/easier way to determine this or not).  I ended up needing the following dependencies:

 

    compileOnly "com.esotericsoftware:kryo:4.0.2"

    compileOnly "de.javakaffee:kryo-serializers:0.42"

    compileOnly "org.apereo.cas:cas-server-support-memcached-core:${casServerVersion}"

    compileOnly "org.apereo.cas:cas-server-core-authentication-attributes:${casServerVersion}"

    compileOnly "org.apereo.cas:cas-server-core-authentication-api:${casServerVersion}"

    compileOnly "org.apereo.cas:cas-server-core-services-api:${casServerVersion}"

    compileOnly "org.apereo.cas:cas-server-core-services-authentication:${casServerVersion}"

    compileOnly "org.apereo.cas:cas-server-core-tickets-api:${casServerVersion}"

    compileOnly "org.apereo.cas:cas-server-core-util-api:${casServerVersion}"

 

Now running ./gradlew clean build  should cause everything will build nicely.

 

 

Alternate Method

 

The other way I did this was to create the .jar file and then deploy that into the overlay.

 

I used the method Julien indicated of cloning the cas project and then making changes to the file(s).  I then ran the following from the module directory (cas/support/cas-server-support-memcached-core in my case):

 

../../gradlew clean build --configure-on-demand --build-cache --parallel -x test -x javadoc -x check --stacktrace -DskipNestedConfigMetadataGen=true -DskipGradleLint=true

 

The .jar file then is created in the build/libs sub-directory.

 

I created src/libs under the cas-overlay and copy the generated .jar file to it.  It doesn’t actually matter where I put the .jar file.  I just thought this seemed to make sense.

 

Then I modified build.gradle and added the following to the dependencies to pick up this local .jar

 

compile files('src/libs/cas-server-support-memcached-core-6.0.3.jar')

 

Again running ./gradlew clean build  should cause everything will build nicely.

Reply all
Reply to author
Forward
0 new messages