Tomcat 上的 Spring Security SAML 元数据 URL

Posted

技术标签:

【中文标题】Tomcat 上的 Spring Security SAML 元数据 URL【英文标题】:Spring Security SAML Metadata URL on Tomcat 【发布时间】:2014-10-02 10:34:12 【问题描述】:

我正在开发一个基于 java 的 Web 应用程序,在 Tomcat 服务器上使用 Spring Security SAML 实现 SSO。此应用程序将扮演服务提供者角色 (SP)。检索此 SP 元数据的默认 Spring URL 是:

https://www.server.com:8080/context/saml/metadata

这工作得很好,按预期返回元数据 XML 文件。但是,当我将 DefaultServlet servlet-mappings 添加到 web.xml 时,我遇到了问题。甚至只是一些基本的东西:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.gif</url-pattern>
</servlet-mapping>

如果 web.xml 中存在一个或多个默认 servlet 映射,则上述 URL 会返回 404。有人知道这可能是什么原因并有可能的解决方案吗?

更新:我已将上面的确切 servlet 映射放在 Spring Security SAML 示例应用程序中,它还会阻止元数据 URL 工作。如果我将其注释掉或删除它,它会按预期工作。下面是那个web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Spring Security SAML</display-name>
<description>Sample application demonstrating Spring security SAML integration.</description>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/securityContext.xml
    </param-value>
</context-param>

<servlet>
    <servlet-name>saml</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>saml</servlet-name>
    <url-pattern>/saml/web/*</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- This servlet mapping prevents the /saml/metadata URL from working. -->
 <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.gif</url-pattern>
</servlet-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/error.jsp</location>
</error-page>


</web-app>

【问题讨论】:

你能发布完整的 web.xml 吗? 完成!有关详细信息,请参阅我的问题中的更新。 【参考方案1】:

我已尝试按照以下步骤重现 Spring SAML 1.0.0.RELEASE 的问题:

已下载 Spring SAML 源代码 将sample/src/main/webapp/WEB-INF/web.xml 替换为您的web.xml 使用gradlew build tomcatRun 启动示例应用程序

但我无法重现您的问题,一切都会继续正常运行。该问题可能是某些 Tomcat 版本所特有的,请尝试按照我的步骤重现它并最终尝试更改您的 Tomcat 版本。

更新:

正如您提到的,在直接部署到 Tomcat 时,我能够复制它。 default servlet 似乎跳过了/* 中定义的过滤器的执行。以下配置应该适合您:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Spring Security SAML</display-name>
    <description>Sample application demonstrating Spring security SAML integration.</description>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/securityContext.xml
        </param-value>
    </context-param>

    <servlet>
        <servlet-name>saml</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>saml</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>/WEB-INF/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/images/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/css/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.gif</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/error.jsp</location>
    </error-page>


</web-app>

确保更改文件org.springframework.security.saml.web.MetadataController 并将@RequestMapping("/metadata") 替换为@RequestMapping("/saml/web/metadata")

【讨论】:

我按照您的步骤操作,它也对我有用。但是,如果我通过 Eclipse(干净编译安装)使用 Maven 构建 WAR 文件并通过 Tomcat 管理器将其部署到 Tomcat 7.0.47,则元数据下载 URL 不起作用。知道为什么它适用于一个而不适用于另一个吗?我对 Gradle 不熟悉。它是使用我安装的同一个 Tomcat 实例还是使用它自己的嵌入式版本?如果是后者,它将使用哪个版本的 Tomcat? 它运行的是 Tomcat 7,但配置可能与独立的 Tomcat 不同。请查看更新后的答案。 您的 web.xml 确实让示例应用程序工作,但我没有看到解决方案是什么。您所做的更改会影响 saml servlet 及其 URL 映射。我的理解是元数据下载 URL 由 MetadataDisplayFilter 处理,它不需要 saml servlet,因为 Spring Security SAML Extension 文档没有提到需要它。如果我删除示例应用程序中的 saml servlet 声明和映射,我希望这不会影响元数据下载,但事实并非如此。您能解释一下您在 web.xml 中的更改如何影响元数据下载吗?谢谢 为了使 /saml/metadata 工作,Tomcat 必须执行 springSecurityFilterChain。由于某些内部 Tomcat 的原因,包含默认的 servlet 映射使 Tomcat 跳过过滤器。通过将“saml”调度程序servlet的映射从/saml/web/*更改为/*,我强制Tomcat使用“saml”servlet处理对/saml/metadata的调用,并正确执行springSecurityFilterChain,然后提供元数据内容. 啊,是的!把这些知识块应用到我自己的应用程序中。我已经让它工作了。感谢您的帮助和耐心!

以上是关于Tomcat 上的 Spring Security SAML 元数据 URL的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 上的 Spring Security SAML 元数据 URL

将 Tomcat 上的 Spring Security 和 Waffle 与角色检查集成

Spring-security、Tomcat 和 SPNEGO - 最佳方法

Spring Security OAuth(angular2上的单独客户端)

Tomcat重启后基于spring security java的配置

Spring Security - 从 Tomcat 6 部署到 Tomcat 7 时凭据错误