Hello,

Did anybody had a similar problem?


Kind regards,

Luis Costa

A quinta-feira, 25 de abril de 2024 à(s) 06:14:16 UTC+1, Luís Costa 
escreveu:

Hello CAS Community,


We are using CAS 6.6.14 for authentication against database and LDAP.


So far our use of CAS 66x is ok, but recently we've encountered a scenario 
a little bit different, that is causing us problems.


The scenario is:

1) after a successeful authentication, if our custom code concludes the 
password is expired,
   we customized the spring web flow "login flow" to move to a custom page 
   with message "your password is expired, you should proceed to Recover 
Password"

2) once we click on a "Recover Password" button, 
   which should provoke navigation to another custom page,
   the following error occurs:

2024-04-16 12:49:12,889 [http-nio-8443-exec-4] WARN : 
org.apereo.cas.authentication.MyCustomAuthenticationHandler
java.io.NotSerializableException: 
org.apereo.cas.authentication.MyCustomAuthenticationHandler
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1187)
at 
java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1572)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1529)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
at java.base/java.util.TreeMap.writeObject(TreeMap.java:2758)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method)
at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at 
java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1070)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1516)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1572)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1529)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1572)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1529)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
at 
java.base/java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:334)
at java.base/java.util.HashMap.writeObject(HashMap.java:1497)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method)
at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at 
java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1070)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1516)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1572)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1529)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1572)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1529)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
at java.base/java.util.HashMap.internalWriteEntries(HashMap.java:1944)
at java.base/java.util.HashMap.writeObject(HashMap.java:1497)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method)
at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at 
java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1070)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1516)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1572)
at 
java.base/java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:443)
at 
org.springframework.webflow.core.collection.LocalAttributeMap.writeObject(LocalAttributeMap.java:333)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method)
at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at 
java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1070)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1516)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1572)
at 
java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1529)
at 
java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1438)
at 
java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1181)
at 
java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
at 
org.apereo.cas.web.flow.executor.EncryptedTranscoder.writeObjectToOutputStream(EncryptedTranscoder.java:89)
at 
org.apereo.cas.web.flow.executor.EncryptedTranscoder.encode(EncryptedTranscoder.java:60)
at 
org.apereo.cas.web.flow.executor.ClientFlowExecutionRepository.getKey(ClientFlowExecutionRepository.java:97)
at 
org.springframework.webflow.engine.impl.FlowExecutionImpl.assignKey(FlowExecutionImpl.java:419)
    (...)


It seems the problemas cause is, the following CAS authentication class,
org.apereo.cas.authentication.DefaultAuthentication 
(which contains a string reference to the successful authentication 
handler),
is beeing store in the flow variable "flowExecutionKey", which in Thymeleaf 
pages is in,
"<input type="hidden" name="execution" th:value="${flowExecutionKey}"/>",
and then, after submiting our custom page,
this flowExecutionKey is deserialized, including the refered class 
DefaultAuthentication.

We found what we think is a temporary fix for this problem,
which is making our 
"org.apereo.cas.authentication.MyCustomAuthenticationHandler" class 
serializable,
but this involves things like having to create new dummy parent class, not 
serializable, with an explicit default constructor,
(because we can't create a default constructor on our class current parent 
class, 
 which is 
org.apereo.cas.adaptors.jdbc.QueryAndEncodeDatabaseAuthenticationHandler)
and having to make some fields transient, to excluded them from 
serialization.

It's true that some CAS authentication related classes are serializable, 
like:
-org.apereo.cas.authentication.DefaultAuthentication
and
-org.apereo.cas.authentication.AuthenticationHandlerExecutionResult

But on the other hand, none of the 
"org.apereo.cas.authentication.AuthenticationHandler" child classes are 
serializable,
and also, the AuthenticationHandlerExecutionResult class only contains a 
"String handlerName" 
(name of the authentication handler that successfully authenticated a 
credential),
not an AuthenticationHandler interface implementation class attribute.


We couldn't find any information about this problem in the following 
sources:
- CAS 6 official site, https://apereo.github.io/cas/6.6.x/
- CAS community, https://groups.google.com/a/apereo.org/g/cas-user?pli=1
- Misagh Moayyed "Fawnoos blog", https://fawnoos.com/blog/



Did anybody had this problem?


Any advice or hint on what's the best solution for this problem?



Kind regards,


Luis Costa

-- 
- 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/a/apereo.org/d/msgid/cas-user/cd509d93-c4b7-458c-a8cf-fca2d278e0bcn%40apereo.org.

Reply via email to