本文介绍了Spring-SAML:传入的 SAML 消息无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将应用与 SAML 集成时遇到问题.

I am facing an issue while integrating my app with SAML.

以下是我的错误:

org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication: Incoming SAML message is invalid
org.opensaml.common.SAMLException: Endpoint with message binding urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST and URL https://myappruldotom/saml/SSO wasn't found in local metadata at org.springframework.security.saml.util.SAMLUtil.getEndpoint(SAMLUtil.java:357) ~[spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]

我的应用程序部署在 AWS 上,当我通过编写自定义 SAMLProcessingFilter 添加日志语句并编写 getEndpoint() 的实现以添加多个日志语句并复制 getEndpoint() 方法的确切内容时.

My app is deployed on AWS and when i added the log statement in by writing the custom SAMLProcessingFilter and wrote implementation of getEndpoint() to add multiple log statements and copied the exact content of getEndpoint() method.

日志语句显示端点以 IP 地址的形式出现:MySAMLProcessingFilter.getEndpoint: MySAMLLOG - endpoint.getLocation() = https://10.193.160.123:443/mysamlapp/saml/SSO

The log statement shows that the endpoint is coming as IP address :MySAMLProcessingFilter.getEndpoint: MySAMLLOG - endpoint.getLocation() = https://10.193.160.123:443/mysamlapp/saml/SSO

我在我的 SAML 配置中定义了 entityId,但这也没有帮助.我的配置文件中的 entityId 为:

I have defined entityId in my SAML config, but this also didn't help. entityId in my config file as :

<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
    <constructor-arg>
        <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
            <property name="entityId" value="https://myappruldotom/mysamlapp/saml/metadata"/>
            <property name="requestSigned" value="false"/>
        </bean>
    </constructor-arg>
</bean>

securityContext.xml 文件:

securityContext.xml file :

<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

<!-- ############################ Security Settings ############################ -->


<!-- Enable auto-wiring -->
<context:annotation-config/>

<!-- Scan for auto-wiring classes in spring saml packages -->
<context:component-scan base-package="org.springframework.security.saml"/>

<!-- IMPORTANT!! This entry is required to enable method-level security. -->
<security:global-method-security pre-post-annotations="enabled"></security:global-method-security>

<!-- No security on resource files -->
<security:http security="none" pattern="/resources/**" />

<!-- Secured pages with SAML as entry point with SPRING CSRF filter -->
<security:http entry-point-ref="samlEntryPoint" disable-url-rewriting="true" use-expressions="true">
    <security:csrf disabled="true"/>
    <security:intercept-url pattern="/cart/**" access="isAuthenticated()"/>
    <security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
    <security:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
</security:http>


<!-- Filters for processing of SAML messages -->
<bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map request-matcher="ant">
        <security:filter-chain pattern="/saml/metadata/**" filters="metadataGeneratorFilter"/>
        <security:filter-chain pattern="/login/**" filters="samlEntryPoint"/>
        <security:filter-chain pattern="/saml/logout/**" filters="samlLogoutFilter"/>
        <security:filter-chain pattern="/saml/SSO/**" filters="samlWebSSOProcessingFilter"/>
        <security:filter-chain pattern="/saml/discovery/**" filters="samlIDPDiscovery"/>
        <security:filter-chain pattern="/saml/SingleLogout/**" filters="samlLogoutProcessingFilter"/>
    </security:filter-chain-map>
</bean>

<bean id="successRedirectHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
    <property name="defaultTargetUrl" value="/cart"/>
</bean>

<!-- After logout, show the logout success page -->
<bean id="successLogoutHandler" class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler">
    <property name="defaultTargetUrl" value="/"/>
</bean>

<!-- Logout handler terminating local session -->
<bean id="logoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
    <property name="invalidateHttpSession" value="true"/>
</bean>

<!-- Handler deciding where to redirect user after failed login -->
<bean id="failureRedirectHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
    <property name="useForward" value="true"/>
</bean>

<security:authentication-manager alias="authenticationManager">
    <!-- Register authentication manager for SAML provider -->
    <security:authentication-provider ref="samlAuthenticationProvider"/>
</security:authentication-manager>

<!-- Central storage of cryptographic keys -->

<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
    <constructor-arg value="classpath:samlKeystore.jks"/>
    <constructor-arg type="java.lang.String" value="nalle123"/>
    <constructor-arg>
        <map>
            <entry key="apollo" value="nalle123"/>
        </map>
    </constructor-arg>
    <constructor-arg type="java.lang.String" value="apollo"/>
</bean>

<!-- Logger for SAML messages and events -->
<bean id="samlLogger" class="org.springframework.security.saml.log.SAMLDefaultLogger"/>

<!-- IDP Discovery Service -->
<bean id="samlIDPDiscovery" class="org.springframework.security.saml.SAMLDiscovery"></bean>


<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
  <constructor-arg>
     <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
        <property name="entityId" value="https://myappdotcom/mysamlapp/saml/metadata"/>
        <property name="requestSigned" value="false"/>
    </bean>
</constructor-arg>
</bean>

<!-- Entry point to initialize authentication, default values taken from properties file -->
<bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint">
   <property name="filterProcessesUrl" value="/saml/SSO"/>
   <property name="defaultProfileOptions">
    <bean class="org.springframework.security.saml.websso.WebSSOProfileOptions">
        <property name="includeScoping" value="false"/>
    </bean>
</property>
</bean>

<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
   <property name="defaultIDP" value="https://dev-942345.oktapreview.com/"/>

   <constructor-arg>
    <list>
        <bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
            <constructor-arg>
                <value type="java.io.File">#{systemProperties['catalina.home']}/saml/idp.xml</value>
            </constructor-arg>
            <property name="parserPool" ref="parserPool"/>
        </bean>
    </list>
</constructor-arg>
</bean>


<!-- SAML Authentication Provider responsible for validating of received SAML messages -->
<bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
   <property name="userDetails" ref="samlUserDetailsService" />
   <property name="forcePrincipalAsString" value="false" />
</bean>


<!-- Custom user details service to attach app specific roles to federated identities -->
<bean id="samlUserDetailsService" class="com.zap.shop.SAMLUserDetailsServiceImpl"></bean>

<!-- Provider of default SAML Context -->
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl"/>

<!-- Processing filter for WebSSO profile messages -->
<bean id="samlWebSSOProcessingFilter" class="org.springframework.security.saml.SAMLProcessingFilter">
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="authenticationSuccessHandler" ref="successRedirectHandler"/>
    <property name="authenticationFailureHandler" ref="failureRedirectHandler"/>
</bean>


<!-- Override default logout processing filter with the one processing SAML messages -->
<bean id="samlLogoutFilter" class="org.springframework.security.saml.SAMLLogoutFilter">
    <constructor-arg index="0" ref="successLogoutHandler"/>
    <constructor-arg index="1" ref="logoutHandler"/>
    <constructor-arg index="2" ref="logoutHandler"/>
</bean>

<!-- Filter processing incoming logout messages -->
<!-- First argument determines URL user will be redirected to after successful global logout -->
<bean id="samlLogoutProcessingFilter" class="org.springframework.security.saml.SAMLLogoutProcessingFilter">
    <constructor-arg index="0" ref="successLogoutHandler"/>
    <constructor-arg index="1" ref="logoutHandler"/>
</bean>

<!-- Class loading incoming SAML messages from httpRequest stream -->
<bean id="processor" class="org.springframework.security.saml.processor.SAMLProcessorImpl">
    <constructor-arg>
        <list>
            <ref bean="redirectBinding"/>
            <ref bean="postBinding"/>
            <ref bean="artifactBinding"/>
            <ref bean="soapBinding"/>
            <ref bean="paosBinding"/>
        </list>
    </constructor-arg>
</bean>

<!-- SAML 2.0 WebSSO Assertion Consumer -->
<bean id="webSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerImpl"/>

<!-- SAML 2.0 Holder-of-Key WebSSO Assertion Consumer -->
<bean id="hokWebSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/>

<!-- SAML 2.0 Web SSO profile -->
<bean id="webSSOprofile" class="org.springframework.security.saml.websso.WebSSOProfileImpl"/>

<!-- SAML 2.0 Holder-of-Key Web SSO profile -->
<bean id="hokWebSSOProfile" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/>

<!-- SAML 2.0 ECP profile -->
<bean id="ecpprofile" class="org.springframework.security.saml.websso.WebSSOProfileECPImpl"/>

<!-- SAML 2.0 Logout Profile -->
<bean id="logoutprofile" class="org.springframework.security.saml.websso.SingleLogoutProfileImpl"/>

<!-- Bindings, encoders and decoders used for creating and parsing messages -->
<bean id="postBinding" class="org.springframework.security.saml.processor.HTTPPostBinding">
    <constructor-arg ref="parserPool"/>
    <constructor-arg ref="velocityEngine"/>
</bean>

<bean id="redirectBinding" class="org.springframework.security.saml.processor.HTTPRedirectDeflateBinding">
    <constructor-arg ref="parserPool"/>
</bean>

<bean id="artifactBinding" class="org.springframework.security.saml.processor.HTTPArtifactBinding">
    <constructor-arg ref="parserPool"/>
    <constructor-arg ref="velocityEngine"/>
    <constructor-arg>
        <bean class="org.springframework.security.saml.websso.ArtifactResolutionProfileImpl">
            <constructor-arg>
                <bean class="org.apache.commons.httpclient.HttpClient">
                    <constructor-arg>
                        <bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"/>
                    </constructor-arg>
                </bean>
            </constructor-arg>
            <property name="processor">
                <bean class="org.springframework.security.saml.processor.SAMLProcessorImpl">
                    <constructor-arg ref="soapBinding"/>
                </bean>
            </property>
        </bean>
    </constructor-arg>
</bean>

<bean id="soapBinding" class="org.springframework.security.saml.processor.HTTPSOAP11Binding">
    <constructor-arg ref="parserPool"/>
</bean>

<bean id="paosBinding" class="org.springframework.security.saml.processor.HTTPPAOS11Binding">
    <constructor-arg ref="parserPool"/>
</bean>

<!-- Initialization of OpenSAML library-->
<bean class="org.springframework.security.saml.SAMLBootstrap"/>

<!-- Initialization of the velocity engine -->
<bean id="velocityEngine" class="org.springframework.security.saml.util.VelocityFactory" factory-method="getEngine"/>

<!-- XML parser pool needed for OpenSAML parsing -->
<bean id="parserPool" class="org.opensaml.xml.parse.StaticBasicParserPool" init-method="initialize">
    <property name="builderFeatures">
        <map>
            <entry key="http://xml.org/sax/features/external-general-entities" value="false"/>
            <entry key="http://javax.xml.XMLConstants/feature/secure-processing" value="true"/>
            <entry key="http://apache.org/xml/features/disallow-doctype-decl" value="true"/>
        </map>
    </property>
</bean>

<bean id="parserPoolHolder" class="org.springframework.security.saml.parser.ParserPoolHolder"/>
</beans>

提前感谢您的帮助.

推荐答案

要解决此问题,请在 metadataGeneratorFilter bean 中设置 MetadataGenerator 的 enityBaseURL 属性.代码如下:

To fix this issue, set the enityBaseURL property of MetadataGenerator inside metadataGeneratorFilter bean. Code looks like this :

<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
        <constructor-arg>
            <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
                <property name="entityId" value="http://myapp.com/myapp/saml/metadata"/>
                <property name="requestSigned" value="false"/>
                <property name="entityBaseURL" value="http://myapp.com/myapp"/>
            </bean>
        </constructor-arg>
    </bean>

这篇关于Spring-SAML:传入的 SAML 消息无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 15:55