Spring Boot - Spring Security Filters的双重初始化

时间:2018-01-19 11:17:06

标签: xml spring-boot spring-security

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

在Spring 3中,我使用了基于XML的Spring Security配置,并定义了类似这样的内容:

<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失败,则会将用户重定向到表单登录。如果请求带有'&amp; form-auth = on'附录的相同网址,则会发生这种情况,因此会激活名为“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都会添加到 ApplicationFilterChain SpringSecurityFilterChain 中。要拒绝Spring Boot将此过滤器添加到ApplicationFilterChain,我必须创建一个FilterRegistrationBean类型的bean并将其设置为disabled。

但是如何为XML元素 sec:intercept-url,sec:http-basic,sec:form-login 创建这样的bean,它隐式地创建GenericFilterBeans,如UsernamePasswordAuthenticationFilter或BasicAuthenticationFilter。 XML元素没有 name id 属性,我可以使用它来创建FilterRegistrationBean。

1 个答案:

答案 0 :(得分:0)

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

简短版本是在其中一个文件夹中添加静态资源,它将映射到'/ **':

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