Spring Security Java Config

29,022

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 )

Share:
29,022
Eugen Halca
Author by

Eugen Halca

Updated on April 26, 2020

Comments

  • Eugen Halca
    Eugen Halca about 4 years

    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 ?