In my Spring Boot appliation I have a following web security config:
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers().frameOptions().disable()
.and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/actuator/**").hasAuthority(Authority.Type.ROLE_ADMIN.getName())
.antMatchers("/login/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.failureUrl("/login?error").permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.and()
.csrf().csrfTokenRepository(csrfTokenRepository()).ignoringAntMatchers("/login/**")
.and()
.addFilterBefore(corsFilter, ChannelProcessingFilter.class)
.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class)
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)
.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint());
// @formatter:on
}
....
}
and ControllerAdvice
:
@ControllerAdvice
public class GlobalControllerExceptionHandler {
private static final String ERROR = "error";
@ExceptionHandler(value = Exception.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public Map<String, ErrorResponse> handleException(Exception exception) {
return createResponseError(exception);
}
private Map<String, ErrorResponse> createResponseError(Exception exception) {
final Map<String, ErrorResponse> responseError = new HashMap<String, ErrorResponse>();
responseError.put(ERROR, new ErrorResponse(exception.getMessage()));
return responseError;
}
}
Right now, when I'm trying to access my secure API urls by anonymous user, I'm receiving a following error:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri May 06 22:59:05 EEST 2016
There was an unexpected error (type=Forbidden, status=403).
Access Denied
Instead of this page, I need to handle such kind of errors in my ControllerAdvice
(in order to return JSON error response) which is working fine for all other exceptions but only for authenticated users.
How to handle this Authentication/Authorization error by my GlobalControllerExceptionHandler
?
ControllerAdvice
s are designed to assist Controller
classes and ExceptionHandler
s are for handling exceptions thrown by Controller
s. AuthenticationException
and AccessDeniedException
s are usually thrown by AbstractSecurityInterceptor
of Spring Security. So, i'm guessing that you won't be able to catch those AuthenticationException
s using ControllerAdvice
s, since ExceptionTranslationFilter
would already catch them and convert them to appropriate HTTP responses.
The better approach is to use exceptionHandling
in your WebSecurityConfigurerAdapter
. Using that, you can configure a AuthenticationEntryPoint
and AccessDeniedHandler
. Here, i'm returning a 403 Forbidden
for access denied cases and a 401 Unauthorized
for missing authentication tokens case:
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.accessDeniedHandler((request, response, accessDeniedException) -> {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
})
.authenticationEntryPoint((request, response, authException) -> {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
});
}
}
Using exceptionHandling
you can configure ExceptionTranslationFilter
to use accessDeniedHandler
for handling AccessDeniedException
s and authenticationEntryPoint
for AuthenticationException
s. Take a peek at ExceptionTranslationFilter
to gain more insight about the process.
If you don't like:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri May 06 22:59:05 EEST 2016
There was an unexpected error (type=Forbidden, status=403).
Access Denied
And want to customize it, you should provide an implementation for ErrorController
and return a Map<String, ErrorResponse>
for errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With