CONNECT 5.1 - SAML Issuer Problem on Audit Message? "Saml Validation error: No message with ID "Not a valid email address.""

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

CONNECT 5.1 - SAML Issuer Problem on Audit Message? "Saml Validation error: No message with ID "Not a valid email address.""

johnhd_at_zen
I'm encountering a strange issue when receiving an XCPD message in my CONNECT 5.1 instance originating from a third-party gateway solution.

In a nutshell, CONNECT 5.1 responds to the XCPD normally, but subsequently throws this error. I believe this error is occurring when CONNECT attempts to validate it's own audit message.

Comparing the XCPDs and their resulting Audit messages side-by-side, I also have a theory as to the cause.

2018-08-02 16:43:28,450 ERROR [gov.hhs.fha.nhinc.callback.cxf.Saml2ExchangeAuthFrameworkValidator] (default task-91) Validation Fail No message with ID "Not a valid email address." found in resource bundle "org/apache/xml/security/resource/xmlsecurity": org.apache.wss4j.common.ext.WSSecurityException: No message with ID "Not a valid email address." found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
	at gov.hhs.fha.nhinc.callback.cxf.Saml2ExchangeAuthFrameworkValidator.validateEmail(Saml2ExchangeAuthFrameworkValidator.java:190) [CONNECTCoreLib-5.1.0.jar:]
	at gov.hhs.fha.nhinc.callback.cxf.Saml2ExchangeAuthFrameworkValidator.validateNameIdFormatValue(Saml2ExchangeAuthFrameworkValidator.java:125) [CONNECTCoreLib-5.1.0.jar:]
	at gov.hhs.fha.nhinc.callback.cxf.Saml2ExchangeAuthFrameworkValidator.validateIssuer(Saml2ExchangeAuthFrameworkValidator.java:92) [CONNECTCoreLib-5.1.0.jar:]
	at gov.hhs.fha.nhinc.callback.cxf.Saml2ExchangeAuthFrameworkValidator.validateAssertion(Saml2ExchangeAuthFrameworkValidator.java:73) [CONNECTCoreLib-5.1.0.jar:]
	at gov.hhs.fha.nhinc.callback.cxf.CONNECTSamlAssertionValidator.validateAssertion(CONNECTSamlAssertionValidator.java:131) [CONNECTCoreLib-5.1.0.jar:]
	at gov.hhs.fha.nhinc.callback.cxf.CONNECTSamlAssertionValidator.validate(CONNECTSamlAssertionValidator.java:260) [CONNECTCoreLib-5.1.0.jar:]
	at org.apache.wss4j.dom.processor.SAMLTokenProcessor.handleSAMLToken(SAMLTokenProcessor.java:162) [wss4j-ws-security-dom-2.1.8.jar:2.1.8]
	at org.apache.wss4j.dom.processor.SAMLTokenProcessor.handleToken(SAMLTokenProcessor.java:89) [wss4j-ws-security-dom-2.1.8.jar:2.1.8]
	at org.apache.wss4j.dom.engine.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:344) [wss4j-ws-security-dom-2.1.8.jar:2.1.8]
	at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:268) [cxf-rt-ws-security-3.1.9.jar:3.1.9]
	at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:171) [cxf-rt-ws-security-3.1.9.jar:3.1.9]
	at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:80) [cxf-rt-ws-security-3.1.9.jar:3.1.9]
	at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:66) [cxf-rt-ws-security-3.1.9.jar:3.1.9]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:252) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274) [cxf-rt-transports-http-3.1.9.jar:3.1.9]
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:248) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:77) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:167) [undertow-servlet-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:761) [undertow-core-1.1.8.Final.jar:1.1.8.Final]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_161]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_161]
	at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_161]

This happens immediately after the "OUTBOUND" message destined for my AuditRepository https://localhost:8181/CONNECTGateway/GatewayService/AuditRepositoryManagerSecuredService.

Here's the full logs (semi-redacted for good form. I remove-and-replaced the client's name, OID, and the base64 of the certs):

FAIL-full_wildfly_logs.txt

I compared these logs side-by-side with another, successful transaction (this one originates from another CONNECT gateway out there):

SUCCESS-full_wilfly_logs.txt

Here's my theory on what's happening:

1) The error is complaining about the <Issuer> element in the security header; specifically that it's not a valid email address.

This is correct, because it's not an email address, it's the Distinguished Name of my gateway's own certificate. The value sort of makes sense because this is an internal message FROM my gateway TO my gateway.

<saml2:Issuer Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">C=US,O=AEGISnetInc,CN=NwHINGatewayTest.ZenGemini.Net</saml2:Issuer>

(yes, you caught me red-handed, I have a DIL cert in there right now. :) )

The reason it's trying to validate that value as an email address is ostensibly because the Format attribute says it's supposed to be one: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress

This VALUE differs from the <Issuer> element on the original XCPD though:

<saml2:Issuer Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">johnhd@consultzen.com</saml2:Issuer> 

Note that the Format attribute is emailAddress here thought! (This comes in later)


2) In my working example, I can find the same audit message, but it seems to be totally different in a few ways:

<saml2:Issuer Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">CN=TEST2,OU=SU,O=xxxxxx,L=Costa Mesa,ST=CA,C=US</saml2:Issuer>

It's an X509SubjectName with a DN value present in it.

Compared to the XCPD:

<saml2:Issuer Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">CN=TEST2,OU=SU,O=xxxxxx,L=Costa Mesa,ST=CA,C=US</saml2:Issuer>

It's identical.

Since this is an internal gateaway-to-itself message, though, I'm a little surprised the value didn't get overwritten? Should it have?

3) So when I pass an email-formatted Issuer, the gateway overwrites the value with the DN of its own certificate, but it doesn't change the Format attribute in a corresponding way. It confuses itself and errors.

This is this the immediate root of the problem.

When I pass an x509-formatted Issuer, the gateway leaves it alone. Because it's a x509-formatted value and is also still flagged as an x509 format, the gateway doesn't complain. But then

To be clear, the question here isn't whether you must use an email or x509 "format" of Issuer (Per Sequoia Auth Framework spec, you're pretty much free to do whatever you want as an Issuer in the XCPD.).

Instead, there are sort of two sub questions here:

A) Should the gateway retain the XCPD's Issuer and use it as the same Issuer in it's Adapter messages?

I almost want to say that it shouldn't, since it's supposed to be generating its own security header to be authenticated by the Audit endpoint.

B) In the case that the issuer is overwritten, the gateway seems to "forget" to change the Format attribute. This should be fixed?

Ask The Experts! Free 15 minute live Q&A sessions with one of Zen's Expert Integrators @ https://consultzen.com/integration-service-desk-solutions/

www.consultzen.com