You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When a SAML IdP is configured to add a OneTimeUse condition to the SAML Assertion, the OpenSamlAuthenticationProvider throws a Saml2Exception and claims that the OneTimeUse condition is an unknown condition.
To Reproduce
Configure an IdP to send the OneTimeUse condition
Attempt to authenticate to the application
Authentication fails due to the Saml2Exception
In Keycloak, the client registration can be configured with the Include OneTimeUse Condition slider to replicate this issue.
Expected behavior
This condition should be parsed and handled appropriately.
Debug Log output
2020-06-26 10:30:35.002 DEBUG 12544 --- [nio-8080-exec-3] .p.s.s.f.Saml2WebSsoAuthenticationFilter : Request is to process authentication
2020-06-26 10:30:35.070 DEBUG 12544 --- [nio-8080-exec-3] s.s.p.s.a.OpenSamlAuthenticationProvider : Validating SAML response from <IdP>
2020-06-26 10:30:35.102 DEBUG 12544 --- [nio-8080-exec-3] s.s.p.s.a.OpenSamlAuthenticationProvider : Validating 1 assertions
2020-06-26 10:30:35.109 DEBUG 12544 --- [nio-8080-exec-3] s.s.p.s.a.OpenSamlAuthenticationProvider : Found 1 validation errors in SAML response [ID_7e615c61-9dda-4629-90fa-989a817c3282]
2020-06-26 10:30:35.109 DEBUG 12544 --- [nio-8080-exec-3] .p.s.s.f.Saml2WebSsoAuthenticationFilter : Authentication request failed: Saml2AuthenticationException{error=[invalid_assertion] Invalid assertion [ID_573ac246-7ea6-4098-af2a-2c97296011dc] for SAML response [ID_7e615c61-9dda-4629-90fa-989a817c3282]}
org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException: An error occurred while validating the assertion: Unknown Condition '{urn:oasis:names:tc:SAML:2.0:assertion}OneTimeUse' of type 'null' in assertion 'ID_573ac246-7ea6-4098-af2a-2c97296011dc'
at org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider.authException(OpenSamlAuthenticationProvider.java:510)
at org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider.validateResponse(OpenSamlAuthenticationProvider.java:320)
at org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider.authenticate(OpenSamlAuthenticationProvider.java:205)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
at org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter.attemptAuthentication(Saml2WebSsoAuthenticationFilter.java:109)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:239)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:353)
at org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter.doFilterInternal(Saml2WebSsoAuthenticationRequestFilter.java:146)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:353)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:353)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:353)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:353)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:353)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:223)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:184)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:141)
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.security.saml2.Saml2Exception: An error occurred while validating the assertion: Unknown Condition '{urn:oasis:names:tc:SAML:2.0:assertion}OneTimeUse' of type 'null' in assertion 'ID_573ac246-7ea6-4098-af2a-2c97296011dc'
at org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider.validateAssertion(OpenSamlAuthenticationProvider.java:403)
at org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider.validateResponse(OpenSamlAuthenticationProvider.java:317)
... 61 common frames omitted
Sample
I've added a OneTimeUse condition test in a commit to my fork here plnordquist@0e5b5a8a34 which replicates this failure.
I think fixing this requires adding a OneTimeUseConditionValidator to the list of ConditionValidators in the OpenSamlAuthenticationProvider but that validator seems to require a ReplayCache that enforces this condition so tokens cannot be replayed.
The text was updated successfully, but these errors were encountered:
Note that a default construction of OneTimeUseConditionValidator was not added to OpenSamlAuthenticationProvider at this time since it's not clear to me how to configure its replay cache without needing to replicate significant portions of the OpenSAML API inside of OpenSamlAuthenticationProvider.
Describe the bug
When a SAML IdP is configured to add a OneTimeUse condition to the SAML Assertion, the OpenSamlAuthenticationProvider throws a Saml2Exception and claims that the OneTimeUse condition is an unknown condition.
To Reproduce
In Keycloak, the client registration can be configured with the Include OneTimeUse Condition slider to replicate this issue.
Expected behavior
This condition should be parsed and handled appropriately.
Debug Log output
Sample
I've added a OneTimeUse condition test in a commit to my fork here plnordquist@0e5b5a8a34 which replicates this failure.
I think fixing this requires adding a
OneTimeUseConditionValidator
to the list ofConditionValidators
in theOpenSamlAuthenticationProvider
but that validator seems to require aReplayCache
that enforces this condition so tokens cannot be replayed.The text was updated successfully, but these errors were encountered: