Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot: accessDeniedHandler does not work

I've got the following Spring Security configuration:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/api/private/**", "/app/**").authenticated();
        http.csrf().disable();
        http.logout().logoutSuccessUrl("/");
        http.exceptionHandling().accessDeniedPage("/403"); //.accessDeniedHandler(accessDeniedHandler);
    }
}

I expect the following logic: not authenticated users will be redirected to /403. Instead of that Spring displays a default Tomcat 403 page. I also tried custom accessDeniedHandler withough any success.

How can I implement custom logic on access failure?

like image 383
fedor.belov Avatar asked Jan 21 '15 00:01

fedor.belov


3 Answers

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.

like image 179
Shaun the Sheep Avatar answered Nov 08 '22 05:11

Shaun the Sheep


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.

like image 10
Sam YC Avatar answered Nov 08 '22 04:11

Sam YC


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");
like image 2
Jaffadog Avatar answered Nov 08 '22 06:11

Jaffadog