Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
I am currently trying to configure SSO with Azure AD in ThingWorx 9.3 without Ping Federate. Support for this was one of the new features introduced with version 9.2
I am following the guide provided by PTC here https://support.ptc.com/help/identity_and_access_management/en/index.html#page/iam/AzureADasCASandIdP.html
But I was not successful. I am ending up with error messages in security log telling me that the SAML response is invalid.
This comes from AuthLog.log:
2022-03-01 09:01:28.160+0100 [L: INFO] [O: o.s.s.s.l.SAMLDefaultLogger] [I: ] [U: ] [S: ] [P: ] [T: https-openssl-nio-443-exec-9] AuthNResponse;FAILURE;10.2.5.4;https://server.domain.com/Thingworx;https://sts.windows.net/8c3fd900-8b7b-45cb-b2a0-aea95fa20530/;;;org.opensaml.common.SAMLException: Response doesn't have any valid assertion which would pass subject validation__ at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:265)__ at com.ptc.eauth.identity.saml2.PTCWebSSOProfileConsumerImpl.processAuthenticationResponse(PTCWebSSOProfileConsumerImpl.java:25)__ at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:88)__ at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)__ at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:92)__ at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)__ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)__ at org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter.doFilter(OAuth2ClientContextFilter.java:60)__ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)__ at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)__ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)__ at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87)__ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)__ at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)__ at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)__ at com.thingworx.security.authentication.sso.ThingworxSSOAuthenticator.authenticate(ThingworxSSOAuthenticator.java:849)__ at com.thingworx.security.authentication.sso.ThingworxSSOAuthenticator.validateAuthenticationRequest(ThingworxSSOAuthenticator.java:1382)__ at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)__ at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)__ at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)__ at java.base/java.lang.reflect.Method.invoke(Method.java:566)__ at com.thingworx.security.authentication.AuthenticationUtilities.validateSSOAuthenticationRequest(AuthenticationUtilities.java:674)__ at com.thingworx.security.authentication.AuthenticationUtilities.validateAuthenticationRequest(AuthenticationUtilities.java:623)__ at com.thingworx.security.authentication.AuthenticationFilter.authenticate(AuthenticationFilter.java:488)__ at com.thingworx.security.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:260)__ at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)__ at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)__ at com.thingworx.security.contenttype.ContentTypeFilter.doFilter(ContentTypeFilter.java:143)__ at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)__ at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)__ at com.thingworx.security.filter.ValidationFilter.doFilter(ValidationFilter.java:22)__ at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)__ at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)__ at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176)__ at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145)__ at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92)__ at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:389)__ at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)__ at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)__ at com.thingworx.security.filter.ClickjackFilter.doFilter(ClickjackFilter.java:298)__ at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)__ at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)__ at com.thingworx.security.filter.HttpResponseHeadersFilter.doFilter(HttpResponseHeadersFilter.java:172)__ at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)__ at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)__ at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)__ at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)__ at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:667)__ at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)__ at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)__ at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)__ at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)__ at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)__ at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)__ at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)__ at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)__ at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726)__ at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)__ at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)__ at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)__ at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)__ at java.base/java.lang.Thread.run(Thread.java:829)__Caused by: org.springframework.security.authentication.InsufficientAuthenticationException: Response doesn't contain any of the requested authentication context class or declaration references__ at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.verifyAuthnContext(WebSSOProfileConsumerImpl.java:638)__ at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.verifyAuthenticationStatement(WebSSOProfileConsumerImpl.java:583)__ at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.verifyAssertion(WebSSOProfileConsumerImpl.java:342)__ at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:250)__ ... 61 more__#
What I could not find out is how the regular expression in "validation.properties" mentioned here should look like for correctly validating the SAML response for Azure AD.
The default REGEX is meant to work with Ping Federate:
Validator.HTTPParameterValue_SAMLResponse=^[a-zA-Z0-9+\/=]*$
Does anyone have a clue if this REGEX needs to be customized to fit for SAML responses from Azure AD? Maybe this helps me to get a working configuration.
Thank you.
Solved! Go to Solution.
The parameter "authnContextAsPassword" was set to true in my sso-settings.json file.
Removing the parameter resolved my issue.
I have the same regex in validation.properties Validator.HTTPParameterValue_SAMLResponse=^[a-zA-Z0-9+\/=]*$ and it works fine for me with Azure AD( Without Ping). Seeing your exception, I don't think there is an issue with the validation file, I believe some settings are not correct (most likely on the Azure AD side). I would recommend you to use SAML traces and debug the issue in the SAML response.
Thank you @Mukul .
It is very helpful to know that you did not have to customize the regular expression.
The parameter "authnContextAsPassword" was set to true in my sso-settings.json file.
Removing the parameter resolved my issue.
Glad to hear that you were able to resolve it.