Spring SAML:SAML 消息的目标端点与收件人端点不匹配
Spring SAML: SAML message intended destination endpoint did not match recipient endpoint
我在应用程序 SP 和客户端 IdP 之间进行 SSO 时收到 'Caused by: org.opensaml.xml.security.SecurityException: SAML message intended destination endpoint did not match recipient endpoint'
异常。
服务器日志显示模式差异,见下文:
Checking SAML message intended destination endpoint against receiver endpoint
2019-03-05 15:02:44.599 DEBUG [204 default task-41][BaseSAMLMessageDecoder] Intended message destination endpoint: https://my.app.com/app-gateway/saml/SSO
2019-03-05 15:02:44.599 DEBUG [204 default task-41][BaseSAMLMessageDecoder] Actual message receiver endpoint: http://my.app.com/app-gateway/saml/SSO
2019-03-05 15:02:44.600 ERROR [204 default task-41][BaseSAMLMessageDecoder] SAML message intended destination endpoint 'https://my.app.com/app-gateway/saml/SSO' did not match the recipient endpoint 'http://my.app.com/app-gateway/saml/SSO'
我的应用程序在 2 个实例上的 STG 上 运行,LB 在前面,因此我使用 SAMLContextProviderLB
上下文提供程序而不是 SAMLContextProviderImpl
:
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderLB">
<property name="scheme" value="https"/>
<property name="serverName" value="my.app.com"/>
<property name="serverPort" value="443"/>
<property name="includeServerPortInRequestURL" value="false"/>
<property name="contextPath" value="/app-gateway"/>
</bean>
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityBaseURL" value="https://my.app.com/app-gateway1"/>
<property name="entityId" value="${cas.sso.entityId}"/>
<property name="includeDiscoveryExtension" value="false"/>
<property name="extendedMetadata" ref="extendedMetadata"/>
<property name="keyManager" ref="keyManager"/>
</bean>
</constructor-arg>
</bean>
在 getActualReceiverEndpointURI
的源代码中,接收方端点 URL 是从请求 httpRequest
obj 中获取的。 因此,我试图了解在哪一步设置了错误的 URL http://my.app.com/app-gateway/saml/SSO。谁能给我解释一下?
protected String getActualReceiverEndpointURI(SAMLMessageContext messageContext) throws MessageDecodingException {
InTransport inTransport = messageContext.getInboundMessageTransport();
if (! (inTransport instanceof HttpServletRequestAdapter)) {
log.error("Message context InTransport instance was an unsupported type: {}",
inTransport.getClass().getName());
throw new MessageDecodingException("Message context InTransport instance was an unsupported type");
}
HttpServletRequest httpRequest = ((HttpServletRequestAdapter)inTransport).getWrappedRequest();
StringBuffer urlBuilder = httpRequest.getRequestURL();
return urlBuilder.toString();
}
您可能需要查看以下页面:
https://developer.jboss.org/thread/240113
我遇到了类似的问题,即使在 LB 上正确设置了 X-Forwarded-Proto,请求仍然仅在 http 中被解释。
后端必须知道 header.
在 http 侦听器上添加 proxy-address-forwarding="true" 和两个 filter-ref
<http-listener name="default" socket-binding="http" proxy-address-forwarding="true"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
希望对您有所帮助,
对于 Apache Tomcat 服务器,它在 AWS Application Load Balancer 后面 运行,需要启用 RemoteIPValue 以便基于 x-forwarded-proto header, Tomcat 将相应地覆盖 scheme(https) & port(443)。
在server.xml
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" internalProxies="10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|169\.254\.\d+\.\d+|127\.\d+\.\d+\.\d+|172\.(1[6-9]|2[0-9]|3[0-1])\.\d+\.\d+" />
我在应用程序 SP 和客户端 IdP 之间进行 SSO 时收到 'Caused by: org.opensaml.xml.security.SecurityException: SAML message intended destination endpoint did not match recipient endpoint'
异常。
服务器日志显示模式差异,见下文:
Checking SAML message intended destination endpoint against receiver endpoint
2019-03-05 15:02:44.599 DEBUG [204 default task-41][BaseSAMLMessageDecoder] Intended message destination endpoint: https://my.app.com/app-gateway/saml/SSO
2019-03-05 15:02:44.599 DEBUG [204 default task-41][BaseSAMLMessageDecoder] Actual message receiver endpoint: http://my.app.com/app-gateway/saml/SSO
2019-03-05 15:02:44.600 ERROR [204 default task-41][BaseSAMLMessageDecoder] SAML message intended destination endpoint 'https://my.app.com/app-gateway/saml/SSO' did not match the recipient endpoint 'http://my.app.com/app-gateway/saml/SSO'
我的应用程序在 2 个实例上的 STG 上 运行,LB 在前面,因此我使用 SAMLContextProviderLB
上下文提供程序而不是 SAMLContextProviderImpl
:
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderLB">
<property name="scheme" value="https"/>
<property name="serverName" value="my.app.com"/>
<property name="serverPort" value="443"/>
<property name="includeServerPortInRequestURL" value="false"/>
<property name="contextPath" value="/app-gateway"/>
</bean>
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityBaseURL" value="https://my.app.com/app-gateway1"/>
<property name="entityId" value="${cas.sso.entityId}"/>
<property name="includeDiscoveryExtension" value="false"/>
<property name="extendedMetadata" ref="extendedMetadata"/>
<property name="keyManager" ref="keyManager"/>
</bean>
</constructor-arg>
</bean>
在 getActualReceiverEndpointURI
的源代码中,接收方端点 URL 是从请求 httpRequest
obj 中获取的。 因此,我试图了解在哪一步设置了错误的 URL http://my.app.com/app-gateway/saml/SSO。谁能给我解释一下?
protected String getActualReceiverEndpointURI(SAMLMessageContext messageContext) throws MessageDecodingException {
InTransport inTransport = messageContext.getInboundMessageTransport();
if (! (inTransport instanceof HttpServletRequestAdapter)) {
log.error("Message context InTransport instance was an unsupported type: {}",
inTransport.getClass().getName());
throw new MessageDecodingException("Message context InTransport instance was an unsupported type");
}
HttpServletRequest httpRequest = ((HttpServletRequestAdapter)inTransport).getWrappedRequest();
StringBuffer urlBuilder = httpRequest.getRequestURL();
return urlBuilder.toString();
}
您可能需要查看以下页面: https://developer.jboss.org/thread/240113
我遇到了类似的问题,即使在 LB 上正确设置了 X-Forwarded-Proto,请求仍然仅在 http 中被解释。 后端必须知道 header.
在 http 侦听器上添加 proxy-address-forwarding="true" 和两个 filter-ref
<http-listener name="default" socket-binding="http" proxy-address-forwarding="true"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
希望对您有所帮助,
对于 Apache Tomcat 服务器,它在 AWS Application Load Balancer 后面 运行,需要启用 RemoteIPValue 以便基于 x-forwarded-proto header, Tomcat 将相应地覆盖 scheme(https) & port(443)。
在server.xml
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" internalProxies="10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|169\.254\.\d+\.\d+|127\.\d+\.\d+\.\d+|172\.(1[6-9]|2[0-9]|3[0-1])\.\d+\.\d+" />