spring-bootspring-securityspring-security-oauth2pre-authentication

per-authentication exceptions are not triggers


I have implemented the pre authentication class and working fine, when authentication success, but when custom exception throw error not displays but redirects to the login page. I want to redirect to the error page when custom exception occurred. I used spring security auth2 and spring boot to develop it.

public class CustomPreAuthenticatedAuthenticationProvider extends PreAuthenticatedAuthenticationProvider {

    private static final Logger LOG = Logger.getLogger(CustomPreAuthenticatedAuthenticationProvider.class);

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        LOG.info("CustomPreAuthenticatedAuthenticationProvider");
        UmUser user = null;
        String name = authentication.getName();
        //        String password = authentication.getCredentials().toString();
        //        String hashedPwd =null;
        user = commonApiCallsService.callUserManagementService(name);

        if (null == user) {
            throw new CustomException(DataConfig.RES_CODE_INTERNAL_ERROR, name + " User not exist.");
        }
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), null, translate(user.getRoles()));

        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        return authenticationToken;
    }

    private Collection << ? extends GrantedAuthority > translate(List < Role > roles) {
        List < GrantedAuthority > authorities = new ArrayList < > ();
        if (null != roles) {
            roles.stream().map((role) - > role.getRoleName().toUpperCase()).map((name) - > {
                if (!name.startsWith("ROLE_")) {
                    name = "ROLE_" + name;
                }
                return name;
            }).forEachOrdered((name) - > {
                authorities.add(new SimpleGrantedAuthority(name));
            });
        }
        return authorities;
    }

}

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

    public ResourceServerInternal() {
        super();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .antMatcher("/internal/**")
            .addFilterAfter(siteminderFilter(), RequestHeaderAuthenticationFilter.class)
            .authorizeRequests()
            .antMatchers("/", "/internal/login*", "/callback/", "/oauth/authorize*", "/exit", "**/logout").permitAll()
            .anyRequest().authenticated();
    }

    @Bean
    public FilterRegistrationBean registration(RequestHeaderAuthenticationFilter filter) throws Exception {
        FilterRegistrationBean registration = new FilterRegistrationBean(filter);
        registration.setEnabled(false);
        return registration;
    }

    @Bean(name = "siteminderFilter")
    public RequestHeaderAuthenticationFilter siteminderFilter() throws Exception {
        RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter = new RequestHeaderAuthenticationFilter();
        requestHeaderAuthenticationFilter.setPrincipalRequestHeader("SM_USER");
        requestHeaderAuthenticationFilter.setAuthenticationManager(authenticationManager());
        return requestHeaderAuthenticationFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.parentAuthenticationManager(authenticationManager());
    }

    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        final List < AuthenticationProvider > providers = new ArrayList < > (1);
        providers.add(preauthAuthProvider());
        return new ProviderManager(providers);
    }

    @Bean(name = "preAuthProvider")
    PreAuthenticatedAuthenticationProvider preauthAuthProvider() throws Exception {
        CustomPreAuthenticatedAuthenticationProvider provider = new CustomPreAuthenticatedAuthenticationProvider();
        provider.setPreAuthenticatedUserDetailsService(userDetailsServiceWrapper());
        return provider;
    }

    @Bean
    UserDetailsByNameServiceWrapper < PreAuthenticatedAuthenticationToken > userDetailsServiceWrapper() throws Exception {
        UserDetailsByNameServiceWrapper < PreAuthenticatedAuthenticationToken > wrapper = new UserDetailsByNameServiceWrapper < > ();
        wrapper.setUserDetailsService(userDetailsService);
        return wrapper;
    }

    @Override
    @Order(1)
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/*.css");
        web.ignoring().antMatchers("/*.js");
        web.ignoring().antMatchers("/css/**");

    }
}

public class CustomException extends AuthenticationException {

    private Integer errorCode;
    private String errorMsg;

    public CustomException(Integer errorCode, String errorMsg) {
        super(errorMsg);
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public Integer getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(Integer errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

}

Solution

  •  I have added `requestHeaderAuthenticationFilter.setContinueFilterChainOnUnsuccessfulAuthentication(false);`
    

    to the siteminderFilter.it works.

     @Bean(name = "siteminderFilter")
            public RequestHeaderAuthenticationFilter siteminderFilter() throws Exception {
                RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter = new RequestHeaderAuthenticationFilter();
                requestHeaderAuthenticationFilter.setPrincipalRequestHeader("user_employee_id");
                requestHeaderAuthenticationFilter.setAuthenticationManager(authenticationManager());
                requestHeaderAuthenticationFilter.setContinueFilterChainOnUnsuccessfulAuthentication(false);
                        return requestHeaderAuthenticationFilter;
            }