0

I'm migrating a Spring 3 webapp to a Spring 4 Spring Boot webapp.

In Spring 3 I used the XML based configuration of Spring Security and defined something like this:

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

Some explanations: The entire page (excluding CSS, JS) is access protected. There are multiple login mechanism like Kerberos (not shown), basic auth and form login. If the preferred login mechanism Kerberos fails, the user is redirected to the form login. This happens when the same url with '&form-auth=on' appendix is requested, so the filter chain named 'formAuth' is activted.

Problem: If I trying to access a JS or CSS file (not protected resource) I got the excepetion 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)

My Assumption Spring Boot adds every GenericFilterBean automatically to the filter chain (see here). So every of my beans of type GenericFilterBean is added to the ApplicationFilterChain and to the SpringSecurityFilterChain. To deny Spring Boot to add this filters to the ApplicationFilterChain I have to create a bean of type FilterRegistrationBean and set it to disabled.

But how can I create such a bean for the XML elements sec:intercept-url, sec:http-basic, sec:form-login which implicitly creates GenericFilterBeans like UsernamePasswordAuthenticationFilter or BasicAuthenticationFilter. The XML elements have no name or id attribute which I can use to create a FilterRegistrationBean.

  • It s a bug/missing feature in Spring Security, see https://github.com/spring-projects/spring-boot/issues/1594 and https://github.com/spring-projects/spring-security/issues/2948. You should use Java configuration. – dur Jan 19 '18 at 12:03
  • Ok. And that works because I does not create a bean in the application context which is catched by spring boot!? – user3762290 Jan 19 '18 at 13:52
  • Sorry, I don't understand your last comment. Spring Boot works with Java configuration, because it is better supported. The main problem is, that Spring Boot registers all servlet filters automatically and IMHO Spring Security has a design error, it uses servlet filter for its security filters. – dur Jan 19 '18 at 13:56

1 Answers1

0

If you are trying to add static resources that does not need to be protected by an auth mechanism you should use the "Static content" feature of spring-boot.

The short version is to add you static resources in one of these folders, and it will be mapped to '/**':

├───src
│   ├───main
│   │     └───resources
│   │            ├───public
│   │            ├───resources
│   │            ├───static
Pär Nilsson
  • 2,259
  • 15
  • 19
  • 1
    I think is not the problem. causes the problem, because the filter is registered out of the FilterChainProxy from Spring Security by Spring Boot (https://github.com/spring-projects/spring-boot/issues/1594). When I remove , I can access the JS or CSS files without exception. But then the entire Page is unprotected. – user3762290 Jan 19 '18 at 13:46
  • If you place your files in the folder I suggested spring generate will add these files to a static resource mapping which I think bypasses the sec filter chain completely – Pär Nilsson Jan 19 '18 at 13:58
  • If OP's configuration is just an addition, it could work, but if OP's configuration is overriding Spring Boot's default configuration, it doesn't work. With Java configuration it depends on `@EnableWebSecurity` anotation, but what is the way to do it in XML? However, OP should try it. – dur Jan 19 '18 at 14:04