Issue
I am upgrading Spring Boot in a small project I use for an Okta proof of concept (all the app does is authenticate with okta and then show a home page - for the most part). I have seen where WebSecurityConfigurerAdapter is being deprecated and wanted to update to the newer methods (https://codejava.net/frameworks/spring-boot/fix-websecurityconfigureradapter-deprecated).
Everything works fine in the Spring Boot 2.5.3 version. After I up the version of Spring Boot to 2.7.3 and the okta spring boot starter to 2.1.6 from 2.1.0, do a Maven->Update Project in Eclipse, I can no longer successfully authenticate. I get the following stack trace
2022-09-09 11:29:17.246 TRACE 22968 --- [nio-8080-exec-5] o.s.s.authentication.ProviderManager : Authenticating request with OpenSaml4AuthenticationProvider (1/1)
2022-09-09 11:29:17.387 DEBUG 22968 --- [nio-8080-exec-5] .s.p.s.a.OpenSaml4AuthenticationProvider : Processing SAML response from http://www.okta.com/exk113scc2hCmGEid0h8
2022-09-09 11:29:17.742 WARN 22968 --- [nio-8080-exec-5] o.o.s.s.a.SAML20AssertionValidator : Signature of Assertion 'id26510770681071201581955264' from Issuer 'http://www.okta.com/exk113scc2hCmGEid0h8' was not valid
2022-09-09 11:29:17.749 DEBUG 22968 --- [nio-8080-exec-5] .s.p.s.a.OpenSaml4AuthenticationProvider : Found 2 validation errors in SAML response [id26510770679528281044304163]: [[invalid_signature] Invalid signature for object [id26510770679528281044304163], [invalid_signature] Invalid assertion [id26510770681071201581955264] for SAML response [id26510770679528281044304163]: Signature of Assertion 'id26510770681071201581955264' from Issuer 'http://www.okta.com/exk113scc2hCmGEid0h8' was not valid]
2022-09-09 11:29:17.751 TRACE 22968 --- [nio-8080-exec-5] .p.s.s.f.Saml2WebSsoAuthenticationFilter : Failed to process authentication request
org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException: Invalid signature for object [id26510770679528281044304163]
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.createAuthenticationException(OpenSaml4AuthenticationProvider.java:698) ~[spring-security-saml2-service-provider-5.7.3.jar:5.7.3]
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.process(OpenSaml4AuthenticationProvider.java:570) ~[spring-security-saml2-service-provider-5.7.3.jar:5.7.3]
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.authenticate(OpenSaml4AuthenticationProvider.java:489) ~[spring-security-saml2-service-provider-5.7.3.jar:5.7.3]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.7.3.jar:5.7.3]
at org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter.attemptAuthentication(Saml2WebSsoAuthenticationFilter.java:113) ~[spring-security-saml2-service-provider-5.7.3.jar:5.7.3]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter.doFilterInternal(Saml2WebSsoAuthenticationRequestFilter.java:192) ~[spring-security-saml2-service-provider-5.7.3.jar:5.7.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:112) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:82) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) ~[spring-security-web-5.7.3.jar:5.7.3]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.44]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.44]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.44]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) ~[spring-boot-actuator-2.7.3.jar:2.7.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.44]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) ~[spring-boot-2.7.3.jar:2.7.3]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) ~[spring-boot-2.7.3.jar:2.7.3]
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) ~[spring-boot-2.7.3.jar:2.7.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) ~[spring-boot-2.7.3.jar:2.7.3]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.44]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[catalina.jar:9.0.44]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[catalina.jar:9.0.44]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[catalina.jar:9.0.44]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) ~[catalina.jar:9.0.44]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[catalina.jar:9.0.44]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[catalina.jar:9.0.44]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-coyote.jar:9.0.44]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-coyote.jar:9.0.44]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-coyote.jar:9.0.44]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-coyote.jar:9.0.44]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-coyote.jar:9.0.44]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:9.0.44]
at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]
I did a saml trace and things look similar with the saml payloads. The IDs, etc are different as expected. The Signature values are different as well. Here is the assertion portion of my saml:
OLD
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
ID="id2634485574464025924231175"
IssueInstant="2022-09-09T15:57:50.115Z"
Version="2.0"
>
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
>http://www.okta.com/exk113scc2hCmGEid0h8</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id2634485574464025924231175">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="xs"
/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>oEj+Jgho7r5rSE9MirhggLlUJ+vm2AbP4j3tBIf8qCA=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>QdnhyP1NaARby0yHLvXjEZl8eDvYOy8ge6ZHrfX4XnfySHkmkoKwqaDeWPSXPH3im1mP3Ch5q8AwZ1aiyvO4bdwqbFlhvaNo7bCYCZD+A1p9CpelD5QlXsUpMHsNE3LKNzxezxr8Pjn9x4+zP8yQMKMr0jxVOc+iDbjRpKvUDFO5WX7xwbBjAemVgk0Vir0rW8MwllgBeCUsCR7oWgJNO5PpjsTgu3S+2tEBpIOuoeSap5oC2TfVTKzID0wY5UtCCKpackDkG0mDVGsA9MJEd2AE4zaRAyk4SWafvjDkEj5RAmrDvb0CuIqphqLaph+SgAVrLE3YgLMnCs/8hRX2Fw==</ds:SignatureValue>
NEW
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
ID="id2643957096229591101765578"
IssueInstant="2022-09-09T15:50:46.615Z"
Version="2.0"
>
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
>http://www.okta.com/exk113scc2hCmGEid0h8</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id2643957096229591101765578">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="xs"
/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>idbj8Fb+1Rbd3HAQHIjCT6bOvTZ6sVvR8uOO21SErIk=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>gqdBS2sccxfD7MNBGyaxljOQxPQGI3SN9Pn3uKwLudN+YkLR7D5Ni25W0JVbxxpK8NobEh1L9lomKVZDmEQNyp4DEyyCd/yth325QuOpdGeJGdbpUs3wVbiN9VpKCf3lby7+r/WQUMwUPVeXI5hm2BJgZCQH83xS3cOg1NKpg4+7wb0Fc1dralTCo2Duq+LYFZMWhwQVk6OwD3gPZv/6bhpNzuop+TE7JQQUHL2ieOlGnoacOFszkVJDbL4+Iy2zUIQ9/FX70XMBnr+cUnt1xtsfeuydPkI+9osT9Uqu40maqMmDjqnF5gTTetTGODkr38XXpWFS/Hi64meQZS0Qnw==</ds:SignatureValue>
Not sure what else would be helpful to post. If anyone has any ideas, or needs to see more, please let me know.
Thanks!
Solution
It is not as simple to just upgrade the versions of Spring Boot and Okta and continue to use the same exact configuration file properties. The old okta config had:
spring:
security:
saml2:
relyingparty:
registration:
okta:
identityprovider:
singlesignon:
url: https://<domain>.oktapreview.com/app/<app-id>/sso/saml
sign-request: false
entity-id: http://www.okta.com/<app-id>
The new property is just looking for the metadata uri:
security:
saml2:
relyingparty:
registration:
okta:
assertingparty:
metadata-uri: https://<domain>.oktapreview.com/app/<app-id>/sso/saml/metadata
Once I followed instructions from @MattRaible's blog that he posted in the comments, I was able to authenticate successfully.
Answered By - B-Wieg
Answer Checked By - David Marino (JavaFixing Volunteer)