在我的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网址时,我收到以下错误:
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
如何处理此身份验证/授权错误? 最佳答案
ControllerAdvice
用于协助Controller
类,而ExceptionHandler
用于处理Controller
引发的异常。 AuthenticationException
和AccessDeniedException
通常由Spring Security的AbstractSecurityInterceptor
抛出。因此,我猜测您将无法使用AuthenticationException
捕获这些ControllerAdvice
,因为ExceptionTranslationFilter
已经捕获了它们并将其转换为适当的HTTP响应。
更好的方法是在exceptionHandling
中使用WebSecurityConfigurerAdapter
。使用它,您可以配置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>
。