我已經實作了AccessDeniedHandler介面,并將該介面添加到WebSecurityConfigurerAdapter中,并且我的ControllerAdvice中還有一個RuntimeException的ExceptionHandler。當我從 MethodSecurity 收到 accessDeniedException 時,ExceptionHandler 在運行 AccessDeniedHandler 之前呼叫 RuntimeException。
如何在不洗掉ExceptionHandler的情況下呼叫AccessDeniedHandler?
這是我的 WebSecurityConfig:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**";
public static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization";
@Value("${payment.gateway.callback-path}")
private String paymentCallbackPath;
@Autowired
private ThingspodAccessDeniedHandler accessDeniedHandler;
@Autowired
private RestAuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private JwtAuthenticationProvider jwtAuthenticationProvider;
protected JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
List<String> pathsToSkip = new ArrayList<>(Collections.singletonList(paymentCallbackPath));
SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, TOKEN_BASED_AUTH_ENTRY_POINT);
JwtAuthenticationFilter filter = new JwtAuthenticationFilter(matcher, JWT_TOKEN_HEADER_PARAM, authenticationFailureHandler);
filter.setAuthenticationManager(authenticationManager());
return filter;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(jwtAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().cacheControl().and().frameOptions().disable()
.and()
.cors()
.and()
.csrf().disable()
.exceptionHandling()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(paymentCallbackPath).permitAll()
.and()
.authorizeRequests()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and()
.authorizeRequests()
.and()
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
}
}
這是我在 ControllerAdvice 中的 AccessDeniedHander 和 ExceptionHandler:
@Component
public class ThingspodAccessDeniedHandler implements AccessDeniedHandler {
private final ObjectMapper mapper;
public ThingspodAccessDeniedHandler(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
Object res = buildResponse(accessDeniedException, "You don't have permission to perform this operation!", HttpStatus.FORBIDDEN, ThingspodErrorCode.PERMISSION_DENIED, request);
response.setStatus(HttpStatus.FORBIDDEN.value());
mapper.writeValue(response.getWriter(), res);
}
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Object> handleAllUncaughtRuntimeException(
RuntimeException ex, WebRequest request){
return buildApiErrorResponse(ex, HttpStatus.INTERNAL_SERVER_ERROR, ThingspodErrorCode.GENERAL, request);
}
uj5u.com熱心網友回復:
選擇錯誤處理程式時,spring 將尋找最具體的錯誤處理程式。
由于您有更一般的例外 ( RuntimeException) 的例外處理程式和AccessDeniedException.
在這種情況下,第一個例外處理程式(用于處理RuntimeException)將不會在AccessDeniedException發生時被呼叫。
因此,您可以保留用于處理 RuntimeExceptions 的例外處理程式,但您需要添加用于處理的例外處理程式AccessDeniedException并將邏輯從ThingspodAccessDeniedHandler該處理程式方法中移出,如下所示:
@ExceptionHandler(UnknownHostException.class)
public void handleUnknownAccessDeniedException(UnknownHostException e, WebRequest request) {
Object res = buildResponse(accessDeniedException, "You don't have permission to perform this operation!", HttpStatus.FORBIDDEN, ThingspodErrorCode.PERMISSION_DENIED, request);
response.setStatus(HttpStatus.FORBIDDEN.value());
mapper.writeValue(response.getWriter(), res);
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Object> handleAllUncaughtRuntimeException(
RuntimeException ex, WebRequest request){
return buildApiErrorResponse(ex, HttpStatus.INTERNAL_SERVER_ERROR, ThingspodErrorCode.GENERAL, request);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/490998.html
