We are using Keycloak for authentication and authorization. On Wildfly 18 and undertow 2.0.27 when logout method is called we are observing class cast exception on Infinispan.
2020-05-18 14:12:37,784 ERROR [org.infinispan.interceptors.impl.InvocationContextInterceptor] (default task-12) ISPN000136: Error executing command RemoveCommand on Cache 'other', writing keys [superadmin]: java.lang.ClassCastException: class org.keycloak.KeycloakPrincipal cannot be cast to class org.infinispan.commons.marshall.WrappedBytes (org.keycloak.KeycloakPrincipal is in unnamed module of loader 'org.keycloak.keycloak-core@10.0.1' @20db1e5c; org.infinispan.commons.marshall.WrappedBytes is in unnamed module of loader 'org.infinispan.commons@9.4.16.Final' @313127c8) at org.infinispan@9.4.16.Final//org.infinispan.container.offheap.OffHeapConcurrentMap.compute(OffHeapConcurrentMap.java:33) at org.infinispan@9.4.16.Final//org.infinispan.container.impl.AbstractInternalDataContainer.remove(AbstractInternalDataContainer.java:186) at org.infinispan@9.4.16.Final//org.infinispan.container.impl.AbstractDelegatingInternalDataContainer.remove(AbstractDelegatingInternalDataContainer.java:42) at org.infinispan@9.4.16.Final//org.infinispan.container.offheap.BoundedOffHeapDataContainer.remove(BoundedOffHeapDataContainer.java:107) at org.infinispan@9.4.16.Final//org.infinispan.container.entries.ReadCommittedEntry.commit(ReadCommittedEntry.java:143) at org.infinispan@9.4.16.Final//org.infinispan.statetransfer.CommitManager.commitEntry(CommitManager.java:139) at org.infinispan@9.4.16.Final//org.infinispan.statetransfer.CommitManager.commit(CommitManager.java:97) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.locking.ClusteringDependentLogic$LocalLogic.commitSingleEntry(ClusteringDependentLogic.java:359) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.locking.ClusteringDependentLogic$AbstractClusteringDependentLogic.commitEntry(ClusteringDependentLogic.java:190) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.EntryWrappingInterceptor.commitContextEntry(EntryWrappingInterceptor.java:584) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.EntryWrappingInterceptor.commitEntryIfNeeded(EntryWrappingInterceptor.java:812) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.EntryWrappingInterceptor.commitContextEntries(EntryWrappingInterceptor.java:566) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.EntryWrappingInterceptor.applyChanges(EntryWrappingInterceptor.java:616) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.EntryWrappingInterceptor.applyAndFixVersion(EntryWrappingInterceptor.java:677) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextThenAccept(BaseAsyncInterceptor.java:105) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.EntryWrappingInterceptor.setSkipRemoteGetsAndInvokeNextForDataCommand(EntryWrappingInterceptor.java:671) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.EntryWrappingInterceptor.visitRemoveCommand(EntryWrappingInterceptor.java:356) at org.infinispan@9.4.16.Final//org.infinispan.commands.write.RemoveCommand.acceptVisitor(RemoveCommand.java:64) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:150) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.locking.AbstractLockingInterceptor.lambda$nonTxLockAndInvokeNext$1(AbstractLockingInterceptor.java:297) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.SyncInvocationStage.addCallback(SyncInvocationStage.java:42) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.InvocationStage.andHandle(InvocationStage.java:65) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.locking.AbstractLockingInterceptor.nonTxLockAndInvokeNext(AbstractLockingInterceptor.java:292) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitNonTxDataWriteCommand(AbstractLockingInterceptor.java:128) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.locking.NonTransactionalLockingInterceptor.visitDataWriteCommand(NonTransactionalLockingInterceptor.java:40) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitRemoveCommand(AbstractLockingInterceptor.java:102) at org.infinispan@9.4.16.Final//org.infinispan.commands.write.RemoveCommand.acceptVisitor(RemoveCommand.java:64) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.DDAsyncInterceptor.visitRemoveCommand(DDAsyncInterceptor.java:65) at org.infinispan@9.4.16.Final//org.infinispan.commands.write.RemoveCommand.acceptVisitor(RemoveCommand.java:64) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndExceptionally(BaseAsyncInterceptor.java:123) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.InvocationContextInterceptor.visitCommand(InvocationContextInterceptor.java:90) at org.infinispan@9.4.16.Final//org.infinispan.interceptors.impl.AsyncInterceptorChainImpl.invoke(AsyncInterceptorChainImpl.java:248) at org.infinispan@9.4.16.Final//org.infinispan.cache.impl.CacheImpl.executeCommandAndCommitIfNeeded(CacheImpl.java:1918) at org.infinispan@9.4.16.Final//org.infinispan.cache.impl.CacheImpl.remove(CacheImpl.java:680) at org.infinispan@9.4.16.Final//org.infinispan.cache.impl.CacheImpl.remove(CacheImpl.java:674) at org.infinispan@9.4.16.Final//org.infinispan.cache.impl.AbstractDelegatingCache.remove(AbstractDelegatingCache.java:453) at org.infinispan@9.4.16.Final//org.infinispan.cache.impl.EncoderCache.remove(EncoderCache.java:684) at org.infinispan@9.4.16.Final//org.infinispan.cache.impl.AbstractDelegatingCache.remove(AbstractDelegatingCache.java:453) at org.picketbox//org.jboss.security.authentication.JBossCachedAuthenticationManager.logout(JBossCachedAuthenticationManager.java:559) at org.wildfly.extension.undertow@18.0.1.Final//org.wildfly.extension.undertow.security.LogoutNotificationReceiver.handleNotification(LogoutNotificationReceiver.java:58) at io.undertow.core@2.0.27.Final//io.undertow.security.impl.AbstractSecurityContext.sendNoticiation(AbstractSecurityContext.java:131) at io.undertow.core@2.0.27.Final//io.undertow.security.impl.AbstractSecurityContext.logout(AbstractSecurityContext.java:142) at io.undertow.core@2.0.27.Final//io.undertow.security.impl.SecurityContextImpl.logout(SecurityContextImpl.java:226) at io.undertow.servlet@2.0.27.Final//io.undertow.servlet.spec.HttpServletRequestImpl.logout(HttpServletRequestImpl.java:505)
When debugged I see that
io.undertow.security.impl.AbstractSecurityContext
has 3 notification receivers and first notification receiver fails.
3 receivers are
org.wildfly.extension.undertow.security.LogoutNotificationReceiver io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler$SecurityNotificationReceiver org.keycloak.adapters.undertow.AbstractUndertowKeycloakAuthMech
Infinispan subsystem
<subsystem xmlns="urn:jboss:domain:infinispan:9.0"> <cache-container name="security" default-cache="auth-cache"> <local-cache name="auth-cache"> <locking acquire-timeout="${infinispan.cache-container.security.auth-cache.locking.acquire-timeout}"/> <off-heap-memory eviction-type="COUNT" size="${infinispan.cache-container.security.auth-cache.eviction.max-entries}"/> <expiration max-idle="-1"/> </local-cache> </cache-container> </subsystem>
Security subsystem
<subsystem xmlns="urn:jboss:domain:security:2.0"> <security-domains> <security-domain name="other" cache-type="infinispan"> <authentication> <login-module code="Remoting" flag="optional"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> <login-module code="RealmDirect" flag="required"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> </authentication> </security-domain> <security-domain name="jboss-web-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> <security-domain name="jboss-ejb-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> </security-domains> </subsystem>
Wildfly extension
<extension module="org.wildfly.extension.security.manager"/>