Spring boot security http basic with oauth2 resource server

2

I am trying to configure a spring boot web application to use the basic http security which will be used for the web pages, and additional I need to implement OAuth2 security for an android application to connect.

The problem I have is that the OAuth security is overwriting the basic http security. Searching in google I found that it is due to the execution order of the security filters, so the ResourceServer with @Order (3) and the WebSecurityConfigurerAdapter with @Order (1) had to be annotated so that the basic security would be applied first . However I find that the basic http starts session well, but when it tries to authenticate the user's roles, it does not take them. The OAuth Authorization server does work and generates the token, but when it tries to access the protected resources, it either takes the roles assigned to the user or simply does not protect the resources. On the other hand when I deactivate one of the two securities (basic http or security OAuth) if the authentication of the roles works correctly and protects the indicated routes.

It's as if by mixing both systems, one overwrites the other.

What would be the correct way to integrate both functions (basic http and OAuth) in the same spring boot application? I read something about http.antMatchers but I can not understand it.

WebSecurityConfig.class

@Configuration
@EnableResourceServer
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private Logger log = LoggerFactory.getLogger(SecurityConfig.class);

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        log.info("Configurando http security web");

        http.httpBasic();

        // Indica los recursos a proteger
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/home", "/about").permitAll()
                .antMatchers("/user/**").authenticated()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/cuenta/**").access("hasAnyRole('USER','ADMIN')");

        // Administra la sesion
        /*http.sessionManagement()
                .invalidSessionUrl("/invalidSession.html")
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);*/

        // Configura el login
        http.formLogin()
                .successHandler(savedRequestAwareAuthenticationSuccessHandler())
                .loginPage("/login").permitAll()
                    .failureUrl("/login?error")
                .loginProcessingUrl("/auth/login_check")
                .usernameParameter("username")
                .passwordParameter("password");

        // Configura el logout
        /*http.logout()
                .permitAll()
                .logoutSuccessUrl("/login?logout");*/

        // Configura la opcion recuerdame de la sesion
        http.rememberMe()
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(60); //1209600

        //super.configure(http);
    }



    @Autowired
    private DataSource dataSource;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public static PasswordEncoder passwordEncoder() {
        //return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setPasswordEncoder(passwordEncoder());
        authProvider.setUserDetailsService(customUserDetailsService);
        return authProvider;
    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl  jdbcTokenRepositoryImpl = new JdbcTokenRepositoryImpl();
        jdbcTokenRepositoryImpl.setDataSource(dataSource);
        return jdbcTokenRepositoryImpl;
    }

    @Bean
    public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler () {
        SavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        authenticationSuccessHandler.setTargetUrlParameter("targetUrl");
        return authenticationSuccessHandler;
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authProvider());
    }
}

ResourceServerConfig.class

@Configuration
@EnableResourceServer
@Order(2)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private Logger log = LoggerFactory.getLogger(ResourceServerConfig.class);

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources
            .resourceId("recursoUno");
    }


    @Override
    public void configure(HttpSecurity http) throws Exception {

        log.info("Configurando http security oauth");

        // Indica los recursos a proteger
        http.authorizeRequests()
                    .antMatchers("/api/v1.0/secure").hasRole("ADMIN")
                    .antMatchers("/api/v1.0/**").authenticated();

        // Configurar el estado de la sesion oauth como stateless
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Habilitar csrf para oauth
        /*http.csrf()
                .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
                .disable();*/


        /*http.authorizeRequests()
                .antMatchers("/api/v1.0/secure").hasRole("ADMIN")
                .antMatchers("/api/v1.0/**").permitAll();*/

        // Configura el logout
        /*http.logout()
                .logoutUrl("/oauth/logout");*/
    }
}
    
asked by wilmerlpr 06.06.2018 в 02:44
source

1 answer

1

Finally I managed to make the basic security http work together with the security oauth I need for the android application. It was not necessary to use the @Order annotation. Thanks to the help published in this link I was able to obtain the answer. Here the code.

WebSecurityConfig.class

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private Logger log = LoggerFactory.getLogger(SecurityConfig.class);

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        log.info("Configurando http security web");

        http.httpBasic();

        // Indica los recursos a proteger
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/home", "/about").permitAll()
                .antMatchers("/user/**").authenticated()
                .antMatchers("/roles/**").hasRole("ADMIN")
                .antMatchers("/admin/**").hasAuthority("ADMIN")
                .antMatchers("/api/**").authenticated()
                .antMatchers("/cuenta/**").access("hasAnyRole('USER','ADMIN')");



        // Administra la sesion
        http.sessionManagement()
                .invalidSessionUrl("/invalid-session.html")
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);

        // Configura el login
        http.formLogin()
                .successHandler(savedRequestAwareAuthenticationSuccessHandler())
                .loginPage("/login").permitAll()
                    .failureUrl("/login?error")
                .loginProcessingUrl("/auth/login_check")
                .usernameParameter("username")
                .passwordParameter("password");

        // Configura el logout
        http.logout()
                .logoutUrl("/logout").permitAll()
                .logoutSuccessUrl("/login?logout");

        // Configura la opcion recuerdame de la sesion
        http.rememberMe()
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(60); //1209600

        //super.configure(http);
    }

    @Autowired
    private DataSource dataSource;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public static PasswordEncoder passwordEncoder() {
        //return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setPasswordEncoder(passwordEncoder());
        authProvider.setUserDetailsService(customUserDetailsService);
        return authProvider;
    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl  jdbcTokenRepositoryImpl = new JdbcTokenRepositoryImpl();
        jdbcTokenRepositoryImpl.setDataSource(dataSource);
        return jdbcTokenRepositoryImpl;
    }

    @Bean
    public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler () {
        SavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        authenticationSuccessHandler.setTargetUrlParameter("targetUrl");
        return authenticationSuccessHandler;
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authProvider());
    }
}

ResourceServer.class

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private Logger log = LoggerFactory.getLogger(ResourceServerConfig.class);

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources
            .resourceId("recursoUno");
    }


    @Override
    public void configure(HttpSecurity http) throws Exception {

        log.info("Configurando http security oauth");

        /* Esta fue la modificacion que se le hizo para que funcione */
        http.requestMatchers()
                .antMatchers("/api/**").and().authorizeRequests()
                    .antMatchers("/api/**").authenticated();

        /* Se cambió esta parte que no funcionaba bien
        http.authorizeRequests()
                    .antMatchers("/**").permitAll()
                    .antMatchers("/api/v1.0/secure").hasRole("ADMIN")
                    .antMatchers("/api/v1.0/**").authenticated();
        */

        // Configurar el estado de la sesion oauth como stateless
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Habilitar csrf para oauth
        /*http.csrf()
                .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
                .disable();*/


        /*http.authorizeRequests()
                .antMatchers("/api/v1.0/secure").hasRole("ADMIN")
                .antMatchers("/api/v1.0/**").permitAll();*/

        // Configura el logout
        /*http.logout()
                .logoutUrl("/oauth/logout");*/
    }
}
    
answered by 06.06.2018 / 05:07
source