Richard G
Richard G

Reputation: 5693

How to configure custom authentication filter in spring security - using java config

I'm trying to configure a custom filter for spring security based authentication. It's a simple override of the usernamepasswordfilter. My problem is I don't know how to configure it using java configuration. Every time I hit "/admin/login" - it's entering my filter and causing an exception rather than going to the login page - but the antmatchers should be allowing access to /admin/login.

If I disable my filter, it works fine. I've read a few of the related questions but none seem to lead me to an answer.

Can anyone advise how to fix my configuration below to support the custom filter?

/**
 * the security configuration.
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Bean
    UserNotifier userNotifier() {
        UserNotifier us = new UserNotifier();
        return us;
    }



    @Bean
    AuthenticationProvider customAuthenticationProvider() {
        SystemUserAuthenticationProvider impl = new SystemUserAuthenticationProvider();

        /* other properties etc */
        return impl ;
    }

    @Bean
    SystemUserService systemUserService(){
        SystemUserService systemUserService = new SystemUserService();
        return systemUserService;
    }

    @Bean
    SystemAuthenticationFilter systemAuthenticationFilter() throws Exception {
        SystemAuthenticationFilter f = new SystemAuthenticationFilter();

        f.setAuthenticationManager(this.authenticationManager());
        f.setPasswordParameter("password");
        f.setUsernameParameter("email");
        f.setPostOnly(true);
        f.setAuthenticationFailureHandler(exceptionMappingAuthenticationFailureHandler());
        f.setAuthenticationSuccessHandler(savedRequestAwareAuthenticationSuccessHandler());
        f.setFilterProcessesUrl("/login");

        return f;
    }

    @Bean
    SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler(){
        SavedRequestAwareAuthenticationSuccessHandler sv = new SavedRequestAwareAuthenticationSuccessHandler();
        sv.setDefaultTargetUrl("/admin/customers");
        return sv;
    }





    @Bean
    AuditorAware<SystemUser> auditorAware(){
        SystemUserAuditorAware adw = new SystemUserAuditorAware();
        return adw;
    }

    @Bean
    ExceptionMappingAuthenticationFailureHandler exceptionMappingAuthenticationFailureHandler(){
        ExceptionMappingAuthenticationFailureHandler ex = new ExceptionMappingAuthenticationFailureHandler();
        Map<String, String> mappings = new HashMap<String, String>();
        mappings.put("org.springframework.security.authentication.CredentialsExpiredException", "/admin/login?reset");
        mappings.put("org.springframework.security.authentication.LockedException", "/admin/login?locked");
        mappings.put("org.springframework.security.authentication.BadCredentialsException", "/admin/login?error");
        mappings.put("org.springframework.security.core.userdetails.UsernameNotFoundException", "/admin/login?error");

        ex.setExceptionMappings(mappings);
        return ex;
    }

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.authenticationProvider(customAuthenticationProvider());
  }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                .antMatchers("/resources/**")
        ;
    }



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

                .authorizeRequests()
                .antMatchers("/admin/login", "/admin/login/new**", "/admin/register", "/admin/logout", "/assets/**", "/admin/session/timeout").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .failureHandler(exceptionMappingAuthenticationFailureHandler())
                .loginProcessingUrl("/login")
                .loginPage("/admin/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .defaultSuccessUrl("/admin/orders")

                .and()
                .logout()
                .logoutUrl("/logout")
                .and()
                .requiresChannel()
                .antMatchers("/admin/**").requiresSecure()
                .and()
                .addFilterBefore(systemAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

}

Upvotes: 2

Views: 1916

Answers (1)

Richard G
Richard G

Reputation: 5693

Never mind, I fixed it by the changing the regex on the login processing url. It seemed to be interfering with the previous antmatcher.

So by changing the login processing url in the form login and custom filter configurations to "log_in", the login page now remains accessible without authorisation.

Upvotes: 1

Related Questions