Hi,
CAS 7.2 fails on SAML2 logout request from IDP and the stacktrace (see below) complains about missing transaction. We use CAS in a clustered environment with a JPA ticket registry. I would have posted this as a bug, but I'm not sure if there's a better place to report bugs for CAS.
We've configured CAS as a SAML2 SP as follows:
cas.authn.pac4j.saml[1].client-name: clientname
cas.authn.pac4j.saml[1].keystore-password: password
cas.authn.pac4j.saml[1].private-key-password: password
cas.authn.pac4j.saml[1].keystore-path: /app/etc/keystore.jks
cas.authn.pac4j.saml[1].service-provider-entity-id: https://ourentityid
cas.authn.pac4j.saml[1].metadata.service-provider.file-system.location: /app/etc/sp.xml
cas.authn.pac4j.saml[1].metadata.identity-provider-metadata-path: /app/etc/idp.xml
cas.authn.pac4j.saml[1].destination-binding: urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
cas.authn.pac4j.saml[1].logout-response-binding-type: urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
cas.authn.pac4j.saml[1].sign-authn-request: true
cas.authn.pac4j.saml[1].wants-assertions-signed: true
cas.authn.pac4j.saml[1].wants-responses-signed: true
cas.authn.pac4j.saml[1].sign-service-provider-logout-request: true
cas.authn.pac4j.saml[1].use-name-qualifier: false
cas.authn.pac4j.saml[1].requested-attributes[0].name: xxx
cas.authn.pac4j.saml[1].requested-attributes[0].friendly-name: xxx
cas.authn.pac4j.saml[1].requested-attributes[0].name-format: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
cas.authn.pac4j.saml[1].requested-attributes[0].required: true
I've shortened the stacktrace a lot but I'm sure the root cause is clearly visible:
ERROR [org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/cas].[dispatcherServlet]] - <Servlet.service() for servlet [dispatcherServlet] in context with path [/cas] threw exception>
java.lang.RuntimeException: jakarta.servlet.ServletException: Request processing failed: org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.apereo.cas.web.flow.actions.logout.DelegatedSaml2ClientLogoutAction@63b0a821 in state 'delegatedAuthenticationIdPLogout' of flow 'login' -- action execution attributes were 'map[[empty]]'
at org.apereo.cas.web.support.filters.AbstractSecurityFilter.throwException(AbstractSecurityFilter.java:42) ~[cas-server-core-web-api-7.2.2.jar!/:7.2.2]
Caused by: jakarta.servlet.ServletException: Request processing failed: org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.apereo.cas.web.flow.actions.logout.DelegatedSaml2ClientLogoutAction@63b0a821 in state 'delegatedAuthenticationIdPLogout' of flow 'login' -- action execution attributes were 'map[[empty]]'
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1022) ~[spring-webmvc-6.2.5.jar!/:6.2.5]
Caused by: org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.apereo.cas.web.flow.actions.logout.DelegatedSaml2ClientLogoutAction@63b0a821 in state 'delegatedAuthenticationIdPLogout' of flow 'login' -- action execution attributes were 'map[[empty]]'
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:62) ~[spring-webflow-3.0.1.jar!/:3.0.1]
Caused by: jakarta.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'flush' call
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:304) ~[spring-orm-6.2.5.jar!/:6.2.5]
at jdk.proxy2/jdk.proxy2.$Proxy246.flush(Unknown Source) ~[?:?]
at org.apereo.cas.ticket.registry.JpaTicketRegistry.getSessionsWithAttributes(JpaTicketRegistry.java:282) ~[cas-server-support-jpa-ticket-registry-7.2.2.jar!/:7.2.2]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:102) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.apereo.cas.monitor.ExecutableObserver.executeJoinPoint(ExecutableObserver.java:82) ~[cas-server-core-api-monitor-7.2.2.jar!/:7.2.2]
at org.apereo.cas.monitor.ExecutableObserver.lambda$observe$0(ExecutableObserver.java:61) ~[cas-server-core-api-monitor-7.2.2.jar!/:7.2.2]
at org.jooq.lambda.Unchecked.lambda$supplier$38(Unchecked.java:1695) ~[jool-0.9.15.jar!/:?]
at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.14.5.jar!/:1.14.5]
at org.apereo.cas.monitor.DefaultExecutableObserver.supply(DefaultExecutableObserver.java:34) ~[cas-server-core-monitor-7.2.2.jar!/:7.2.2]
at org.apereo.cas.monitor.ExecutableObserver.observe(ExecutableObserver.java:61) ~[cas-server-core-api-monitor-7.2.2.jar!/:7.2.2]
at org.apereo.cas.monitor.ExecutableObserver.observe(ExecutableObserver.java:76) ~[cas-server-core-api-monitor-7.2.2.jar!/:7.2.2]
at org.apereo.cas.config.CasCoreTicketsMonitoringConfiguration$TicketRegistryMonitoringAspect.aroundTicketRegistryOperations(CasCoreTicketsMonitoringConfiguration.java:49) ~[cas-server-core-tickets-7.2.2.jar!/:7.2.2]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:642) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:632) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.5.jar!/:6.2.5]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.5.jar!/:6.2.5]
at jdk.proxy2/jdk.proxy2.$Proxy248.getSessionsWithAttributes(Unknown Source) ~[?:?]
at org.apereo.cas.web.flow.actions.logout.DelegatedSaml2ClientLogoutAction.lambda$removeSsoSessionsForSessionIndexes$2(DelegatedSaml2ClientLogoutAction.java:54) ~[cas-server-support-pac4j-saml-7.2.2.jar!/:7.2.2]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
at org.apereo.cas.web.flow.actions.logout.DelegatedSaml2ClientLogoutAction.removeSsoSessionsForSessionIndexes(DelegatedSaml2ClientLogoutAction.java:53) ~[cas-server-support-pac4j-saml-7.2.2.jar!/:7.2.2]
at org.apereo.cas.web.flow.actions.logout.DelegatedSaml2ClientLogoutAction.doExecuteInternal(DelegatedSaml2ClientLogoutAction.java:70) ~[cas-server-support-pac4j-saml-7.2.2.jar!/:7.2.2]
at org.apereo.cas.web.flow.actions.BaseCasWebflowAction.doExecute(BaseCasWebflowAction.java:57) ~[cas-server-core-webflow-api-7.2.2.jar!/:7.2.2]