So recently I migrated the Spring configuration from XML to Java config. It's a Spring OAuth 2 Server, and some endpoints are secured with clients authentication, and some endpoints (confirm_access) are secured with user authentication, which is delegated to login application with a redirect made from a filter ("authenticationFilter"). But I'm not able to do the same with Spring Security Java config :
Here my working security XML configuration :
<sec:http pattern="/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
entry-point-ref="oauthAuthenticationEntryPoint">
<sec:intercept-url pattern="/token" access="IS_AUTHENTICATED_FULLY" />
<sec:anonymous enabled="false" />
<sec:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<sec:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<sec:http pattern="/css/**" security="none" />
<sec:http pattern="/js/**" security="none" />
<sec:http access-denied-page="/errors/access-denied.html" disable-url-rewriting="true" entry-point-ref="authenticationEntryPoint">
<sec:intercept-url pattern="/authorize" access="ROLE_USER" />
<sec:intercept-url pattern="confirm_access" access="ROLE_USER" />
<sec:intercept-url pattern="/device/authorize" access="ROLE_USER" />
<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:custom-filter ref="authenticationFilter" before="ANONYMOUS_FILTER" />
<sec:anonymous />
</sec:http>
<sec:authentication-manager id="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="authenticationProvider" />
</sec:authentication-manager>
<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
Here is my Java config attempt :
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
@Order(1)
@Import({WebSecurityConfig.TokenEndpointSecurityConfigurationAdapter.class,
WebSecurityConfig.ResourceSecurityConfigurationAdapter.class,
WebSecurityConfig.AnonymousSecurityConfigurationAdapter.class})
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
ClientDetailsUserDetailsService clientDetailsUserService;
@Bean(name = "clientAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(clientDetailsUserService);
}
@Configuration
@Order(2)
public static class TokenEndpointSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
ClientDetailsUserDetailsService clientDetailsUserService;
@Autowired
OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint;
@Autowired
ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter;
@Autowired
OAuth2AccessDeniedHandler oauthAccessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.userDetailsService(clientDetailsUserService)
.anonymous().disable()
.authorizeUrls()
.antMatchers("/token")
.fullyAuthenticated()
.and()
.httpBasic()
.authenticationEntryPoint(oauthAuthenticationEntryPoint)
.and()
.addFilterBefore(clientCredentialsTokenEndpointFilter, BasicAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.stateless)
.and()
.exceptionHandling().accessDeniedHandler(oauthAccessDeniedHandler);
}
}
@Configuration
@Order(3)
public static class ResourceSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter{
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/css/**","/js/**");
}
}
@Configuration
@Order(4)
public static class AnonymousSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter{
@Autowired
OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint;
@Autowired
AuthenticationFilter authenticationFilter;
@Autowired
PreAuthenticatedAuthenticationProvider authenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authenticationProvider(authenticationProvider)
.addFilterBefore(authenticationFilter, AnonymousAuthenticationFilter.class)
.authorizeUrls().anyRequest().anonymous()
.and()
.authorizeUrls()
.antMatchers("/authorize","confirm_access","/custom/authorize")
.hasRole("USER")
.and()
.exceptionHandling().accessDeniedPage("/errors/access-denied.html");
}
}
}
With this config Spring Security tries to authenticate user for all endpoints, and displays generate login form, so custom filter is not added.
Where is my mistake ?
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. Spring Security is a framework that focuses on providing both authentication and authorization to Java applications.
If Spring Security is on the classpath, Spring Boot automatically secures all HTTP endpoints with “basic” authentication. However, you can further customize the security settings. The first thing you need to do is add Spring Security to the classpath.
Since your original configuration only contains two http
elements your new configuration should only contain two WebSecurityConfigurerAdapter
instances. Each WebSecurityConfigurerAdapter
instance is mapped using the http.antMatchers
. Currently WebSecurityConfigurerAdapter
is mapped to every URL.
You can refer to the reference for an example of how to use multiple WebSecurityConfigurerAdapter
instances (which is the equivalent of )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With