Creating multiple HTTP sections in Spring Security Java Config
Using Spring Security XML configuration, you can define multiple HTTP elements to specify different access rules for different parts of your application. The example given in 8.6 Advanced Namespace Configuration defines separate stateful and stateless sections of the application, with the former using sessions and form login, and the latter using no sessions and BASIC authentication:
<!-- Stateless RESTful service using Basic authentication -->
<http pattern="/restful/**" create-session="stateless">
<intercept-url pattern='/**' access='ROLE_REMOTE' />
<http-basic />
</http>
<!-- Empty filter chain for the login page -->
<http pattern="/login.htm*" security="none"/>
<!-- Additional filter chain for normal users, matching all other requests -->
<http>
<intercept-url pattern='/**' access='ROLE_USER' />
<form-login login-page='/login.htm' default-target-url="/home.htm"/>
<logout />
</http>
I can't figure out how to do the same thing with Java Config. It's important that I disable sessions and use a different entry point for my web services. Right now I have the following:
@Override
public void configure(WebSecurity security)
{
security.ignoring().antMatchers("/resource/**", "/favicon.ico");
}
@Override
protected void configure(HttpSecurity security) throws Exception
{
security
.authorizeRequests()
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/login").failureUrl("/login?loginFailed")
.defaultSuccessUrl("/ticket/list")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and().logout()
.logoutUrl("/logout").logoutSuccessUrl("/login?loggedOut")
.invalidateHttpSession(true).deleteCookies("JSESSIONID")
.permitAll()
.and().sessionManagement()
.sessionFixation().changeSessionId()
.maximumSessions(1).maxSessionsPreventsLogin(true)
.sessionRegistry(this.sessionRegistryImpl())
.and().and().csrf()
.requireCsrfProtectionMatcher((r) -> {
String m = r.getMethod();
return !r.getServletPath().startsWith("/services/") &&
("POST".equals(m) || "PUT".equals(m) ||
"DELETE".equals(m) || "PATCH".equals(m));
});
}
Using this I was able to disable CSRF protection for my web services. But I really need a whole separate HTTP configuration so that I can disable sessions and specify a different entry point. I know I can use requestMatcher
or requestMatchers
to restrict the URIs that it applies to, but it doesn't appear that you can use this to create separate configurations. It's almost like I need two configure(HttpSecurity security)
methods.
In Spring Security to mimic the behavior of multiple <http>
elements from XML in Java config create multiple classes for security configuration. In general it is the best/easiest to create a common security configuration with multiple inner classes for the security definition for HttpSecurity
. See here for a sample.
And here the related section in the official Spring Security documentation:
5.7 Multiple HttpSecurity