[英]Spring ControllerAdvice and authentication/authorization exception handling
在我的Spring Boot應用程序中,我具有以下Web安全配置:
@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
}
....
}
和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;
}
}
現在,當我試圖由匿名用戶訪問我的安全API URL時,我收到以下錯誤:
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
而不是此頁面,我需要在ControllerAdvice
處理此類錯誤(以返回JSON錯誤響應),該錯誤對於所有其他異常均正常,但僅對經過身份驗證的用戶有效。
如何通過我的GlobalControllerExceptionHandler
處理此Authentication / Authorization錯誤?
ControllerAdvice
旨在幫助Controller
類,而ExceptionHandler
則用於處理Controller
拋出的異常。 AuthenticationException
和AccessDeniedException
通常由Spring Security的AbstractSecurityInterceptor
拋出。 因此,我猜測您將無法使用ControllerAdvice
捕獲那些AuthenticationException
,因為ExceptionTranslationFilter
已經捕獲了它們並將它們轉換為適當的HTTP響應。
更好的方法是在WebSecurityConfigurerAdapter
使用exceptionHandling
。 使用它,您可以配置AuthenticationEntryPoint
和AccessDeniedHandler
。 在這里,我將為拒絕訪問的情況返回403 Forbidden
訪問,對於缺少身份驗證令牌的情況返回401 Unauthorized
:
@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);
});
}
}
使用exceptionHandling
可以將ExceptionTranslationFilter
配置為使用accessDeniedHandler
來處理AccessDeniedException
並使用authenticationEntryPoint
來AuthenticationException
。 窺視ExceptionTranslationFilter
以獲取有關該過程的更多見解。
如果您不喜歡:
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
並且想要對其進行自定義,您應該提供ErrorController
的實現,並返回Map<String, ErrorResponse>
以獲取錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.