访问没有斜杠的 Tomcat 应用程序时,Spring Security Context 为空

Posted

技术标签:

【中文标题】访问没有斜杠的 Tomcat 应用程序时,Spring Security Context 为空【英文标题】:Spring Security Context is null when accessing Tomcat application without trailing slash 【发布时间】:2016-11-22 15:26:41 【问题描述】:

我在 Tomcat 7 上部署了一个基于 Spring 的 Web 应用程序。运行它的方法是将 application.war 存档复制到 webapps 目录并启动服务器,因此我的应用程序根在 https://localhost:8443/application/ 下可用。

然后我想向它添加 Spring 安全性(3.2.4)。我的目的是保护整个应用程序,而不仅仅是其中的一部分。我拥有的 Spring 安全配置:

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

    <http auto-config="true">
        <intercept-url pattern="/**" access="ROLE_USER" />
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="admin" password="admin" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>

</beans:beans>

web.xml:

<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>

这是一个基本配置,可以在官方文档和许多教程中找到。一切正常,当我没有通过身份验证时,Spring 将我重定向到它的默认登录页面。然后我可以登录并访问应用程序,直到会话到期或导航到注销 url。

当我访问没有尾部斜杠的应用程序根目录时,问题开始出现:https://localhost:8443/application

Spring 找不到安全上下文:

2016-07-19 17:48:36,650 DEBUG: security.web.FilterChainProxy - / at position 1 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-07-19 17:48:36,650 DEBUG: web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-07-19 17:48:36,650 DEBUG: web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@53b1e801. A new one will be created.

然后我被重定向到登录页面,但是在我登录后我被重定向到没有斜杠的原始 URL,Spring 再次失败,我再次看到登录表单。

有人知道为什么会这样吗?我的配置是最小的,使用开箱即用的默认值。用例也很简单,感觉很奇怪,这没有按预期工作。我觉得我缺少一些基本的东西,无论是 Spring 还是 Tomcat。

任何帮助将不胜感激,谢谢。

【问题讨论】:

【参考方案1】:

试试这个

<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>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/</url-pattern>
</filter-mapping>

【讨论】:

不幸的是,这并没有帮助,仍然是相同的结果。【参考方案2】:
<http auto-config="true">
    <!-- my be this can`t match -->
    <intercept-url pattern="/**" access="ROLE_USER" />
     <!-- add this  for try -->
     <intercept-url pattern="/" access="ROLE_USER" />
</http>

【讨论】:

尝试重新排列模式,例如 虽然此代码可以回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将改善答案的长期价值。【参考方案3】:

问题出在 JSESSIONID cookie 路径上——Tomcat 自动将其设置为 /application/,因此任何访问应用程序根目录且不带斜杠的请求都被视为需要身份验证的新用户。将 cookie 路径设置为 /application 为我解决了这个问题。

【讨论】:

以上是关于访问没有斜杠的 Tomcat 应用程序时,Spring Security Context 为空的主要内容,如果未能解决你的问题,请参考以下文章

关于tomcat会在url末尾自动追加斜杠(/)

为啥共享访问时,在共享IP前要加2和斜杠,???反方向的斜杠就不行?

idea中SpringBoot热部署时mapping偶然出现丢失的问题。

如何在没有斜杠的情况下访问目录的 index.php 并且不获得 301 重定向

当 URL 路径中出现双斜杠时,如何使用 Elastic Beanstalk (Apache+Tomcat) 解决 HTTP 404 错误,例如https://uat.myserver//rest/s

URL最后结尾反斜杠(/)加与不加区别