Search code examples
javaspringspring-mvcspring-securityaccess-denied

How to fix overriding of default AccessDeniedHandler (AccessDeniedHandlerImpl) in Spring Security (Java) config?


I have a small web application based on Spring MVC and Spring Security. I have difficulties setting my own AccessDeniedHandler that should redirect unauthorized users to my custom error page.

I use http.exceptionHandling().accessDeniedHandler(accessDeniedHandler) in my config class that extends WebSecurityConfigurerAdapter. The default AccessDeniedHandler keeps being invoked despite the setting (I debugged ExceptionTranslationFilter). As a result the container-defined error page is displayed instead of my custom one.

Do you have an idea what I am missing here? What could be the issue? Thank you kindly for your help.

An excerpt from my WebSecurityConfigurerAdapter super class:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/static/**", "/login/*", "/login").permitAll()
                .antMatchers("/site/admin*").hasRole("ADMIN")
                .anyRequest().authenticated()
            .and().formLogin()
                .loginPage("/login")
                .usernameParameter("user-name")
                .passwordParameter("password")
                .defaultSuccessUrl("/site/welcome", true)
                .loginProcessingUrl("/process-login")
                .failureUrl("/login?login_error=1")
            .and().logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login")
            .and().sessionManagement()
                .invalidSessionUrl("/login")
            .and().csrf()
            .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler);
}

My custom AccessDeniedHandler implementation:

@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    private static Logger LOG = Logger.getLogger(CustomAccessDeniedHandler.class);

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
            AccessDeniedException accessDeniedException) throws IOException, ServletException {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            LOG.warn(String.format("User [%s] attempted to access the protected URL [%s]!", authentication.getName(), request.getRequestURI()));
        }

        response.sendRedirect(request.getContextPath() + "/site/403");
    }
}

Solution

  • I forgot to assign the autowired constructor parameter to a field! I am sorry for posting such a trivial problem here, but after I spent half a day looking for a solution, I was blind and I missed it...

    public SpringSecurityConfiguration(
                AccessDeniedHandler accessDeniedHandler, ...) {
            this.accessDeniedHandler = accessDeniedHandler; // This line was missing.
            ...
    }