【问题标题】:Spring Boot - double initialization of Spring Security Filters [duplicate]Spring Boot - Spring Security Filters的双重初始化[重复]
【发布时间】:2018-06-28 14:58:18
【问题描述】:

我正在将 Spring 3 webapp 迁移到 Spring 4 Spring Boot webapp。

在 Spring 3 中,我使用了 Spring Security 的基于 XML 的配置,并定义了如下内容:

<sec:http pattern="/**/*.css" security="none" />
<sec:http pattern="/**/*.js" security="none" />

<sec:http pattern="^.*\?basic-auth=on$" request-matcher="regex" create-session="never">
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
    <sec:http-basic />
</sec:http>

<sec:http name="formAuth" pattern="^(.*(\?|&amp;)form-auth=on)|/servlet/login\.html|/servlet/!login\.html$" request-matcher="regex"
    entry-point-ref="security.formLogin.entryPoint">

    <sec:intercept-url pattern="/servlet/login.html" access="IS_AUTHENTICATED_ANONYMOUSLY"  />
    <sec:intercept-url pattern="/servlet/!login.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />

    <sec:form-login login-page="/servlet/login.html"
        login-processing-url="/servlet/!login.html"
                    default-target-url="/" authentication-failure-handler-ref="accessDeniedHandler"></sec:form-login>
</sec:http>

一些解释: 整个页面(不包括 CSS、JS)都受访问保护。 有多种登录机制,如 Kerberos(未显示)、基本身份验证和表单登录。如果首选登录机制 Kerberos 失败,用户将被重定向到表单登录。当请求带有 '&form-auth=on' 附录的相同 url 时会发生这种情况,因此名为 'formAuth' 的过滤器链被激活。

问题: 如果我尝试访问 JS 或 CSS 文件(不受保护的资源),我得到了异常 AuthenticationCredentialsNotFoundException

    org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:379)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:223)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)

我的假设 Spring Boot 自动将每个 GenericFilterBean 添加到过滤器链 (see here)。 所以我的每一个 GenericFilterBean 类型的 bean 都被添加到 ApplicationFilterChainSpringSecurityFilterChain 中。要拒绝 Spring Boot 将此过滤器添加到 ApplicationFilterChain,我必须创建一个 FilterRegistrationBean 类型的 bean 并将其设置为禁用。

但是我怎样才能为 XML 元素 sec:intercept-url, sec:http-basic, sec:form-login 创建这样的 bean,它隐式地创建像 UsernamePasswordAuthenticationFilter 或 BasicAuthenticationFilter 这样的 GenericFilterBeans。 XML 元素没有可用于创建 FilterRegistrationBean 的 nameid 属性。

【问题讨论】:

  • 这是 Spring Security 中的一个错误/缺失功能,请参阅 github.com/spring-projects/spring-boot/issues/1594github.com/spring-projects/spring-security/issues/2948。您应该使用 Java 配置。
  • 好的。之所以有效,是因为我没有在 Spring Boot 捕获的应用程序上下文中创建 bean!?
  • 对不起,我不明白你最后的评论。 Spring Boot 与 Java 配置一起工作,因为它得到了更好的支持。主要问题是,Spring Boot 自动注册所有 servlet 过滤器,恕我直言 Spring Security 存在设计错误,它使用 servlet 过滤器作为其安全过滤器。

标签: xml spring-boot spring-security


【解决方案1】:

如果您尝试添加不需要通过身份验证机制保护的静态资源,您应该使用 spring-boot 的"Static content" 功能。

简短的版本是在这些文件夹之一中添加您的静态资源,它将映射到'/**':

├───src
│   ├───main
│   │     └───resources
│   │            ├───public
│   │            ├───resources
│   │            ├───static

【讨论】:

  • 我认为 不是问题。 导致问题,因为过滤器是由 Spring Boot (github.com/spring-projects/spring-boot/issues/1594) 从 Spring Security 的 FilterChainProxy 注册的。当我删除 时,我可以毫无例外地访问 JS 或 CSS 文件。但是整个页面都没有受到保护。
  • 如果您将文件放在我建议 spring generate 的文件夹中,会将这些文件添加到我认为完全绕过 sec 过滤器链的静态资源映射中
  • 如果 OP 的配置只是一个补充,它可以工作,但如果 OP 的配置覆盖 Spring Boot 的默认配置,它就不起作用。对于 Java 配置,它依赖于 @EnableWebSecurity 注释,但是在 XML 中实现它的方法是什么?但是,OP 应该尝试一下。
猜你喜欢
  • 2017-06-11
  • 2021-10-20
  • 1970-01-01
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 2021-04-03
  • 1970-01-01
相关资源
最近更新 更多