Spring Boot: accessDeniedHandler does not work

Use this:-

@Configuration
public class ViewRegistryConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/403").setViewName("notAuth");
    }

}

and create notAuth.html page in your template folder


The AccessDeniedHandler only applies to authenticated users. The default behaviour for unauthenticated users is to redirect to the login page (or whatever is appropriate for the authentication mechanism in use).

If you want to change that you need to configure an AuthenticationEntryPoint, which is invoked when an unauthenticated user attempts to access a protected resource. You should be able to use

http.exceptionHandling().authenticationEntryPoint(...)

instead of what you have. For more details, check the API docs.


The normal Spring Security behavior is to redirect unauthenticated users to your login page as configured below. Authenticates users who are not authorized (dont have the ADMIN role) will be directed to the access denied page:

http.authorizeRequests().antMatchers("/admin/**")
    .access("hasRole('ADMIN')")
    .and().formLogin().loginPage("/login")
    .and().exceptionHandling().accessDeniedPage("/403");

If you have implemented your own authentication mechanism and you are not counting on the Spring Security configuration to deliver unauthenticated users to your login page, you can game the Spring Security configuration as follows - to serve your custom 403 page instead of a real login page:

http.authorizeRequests().antMatchers("/admin/**")
    .access("hasRole('ADMIN')")
    .and().formLogin().loginPage("/403")
    .and().exceptionHandling().accessDeniedPage("/403");

Come across this question, it helped me solve my problem, below is my code:

public class CustomHttp403ForbiddenEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authException) throws IOException, ServletException {
        response.getWriter().print("You need to login first in order to perform this action.");
    }

}

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException arg2)
            throws IOException, ServletException {
        response.getWriter().print("You don't have required role to perform this action.");
    }

}

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

    http.exceptionHandling().accessDeniedHandler(new CustomAccessDeniedHandler()).and()
        .exceptionHandling().authenticationEntryPoint(new CustomHttp403ForbiddenEntryPoint());
}

Hope this helps.