Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security Java Config

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 ?

like image 527
Eugen Halca Avatar asked Nov 21 '13 20:11

Eugen Halca


People also ask

What is Spring Security Config?

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.

What is security configuration in Spring Boot?

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.


1 Answers

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 )

like image 155
Rob Winch Avatar answered Oct 13 '22 03:10

Rob Winch