Spring Security:安全过滤器内抛出的异常映射

问题描述 投票:2回答:2

我有自定义安全过滤器,作为额外的授权步骤。

过滤器检查用户是否可以被授权并在用户不应该访问资源时抛出异常。

问题是,如果我从过滤器中抛出一个异常 - 它没有被映射到正确的状态代码(在我的情况下,我需要HTTP 403)。

我不能使用@ControllerAdvice@ExceptionHandler,因为security filters work before controller handling

我想可能是我做错了我不应该抛出异常,或者我应该抛出一个非常具体的异常。

问:有没有办法自动将过滤器中的异常映射到正确的状态代码?或者有没有办法实现过滤器没有例外?

注意:我也读过this post,但是从调试中我看到我的过滤器链不包含ExceptionTranslationFilter

java spring security spring-security http-status-codes
2个回答
0
投票

或者有没有办法实现过滤器没有例外?

显然,您可以直接写入响应并从捕获身份验证或授权失败的那一点返回。因为我只有一个JWT身份验证过滤器实现,所以抛出异常然后全局处理它似乎太多不必要的过度工作 - AbstractAuthenticationProcessingFilter

每当不满足身份验证条件时,如JWT令牌解析问题,丢失令牌,格式错误的令牌等,我只需记录错误,设置HttpStatus并从null方法返回attemptAuthentication

这样我的整个逻辑就封装在单个类中。我还必须为所有情况发送401,但错误消息不同,并且由一个简单的实用方法处理。

如果您必须从应用程序中的许多地方执行此操作,我发现抛出然后处理异常没有任何错误,在这种情况下,处理程序可以在Nicholas Smith的答案中指定。


-1
投票

Spring推荐的方法是有一个@Component实现AccessDeniedHandler然后在你的类中扩展WebSecurityConfigurerAdapter将其注册到.accessDeniedHandler()方法中的configure(HttpSecurity ...)。这是为403,如果你想要包装401错误,那么你需要扩展Http401AuthenticationEntryPoint。我将专注于下面的403案例。

您的WebSecurityConfigurerAdapter

@Override
  protected void configure(final HttpSecurity http) throws Exception {
    ...
    http
        .csrf().disable()
        .exceptionHandling().authenticationEntryPoint(<YOUR Http401AuthenticationEntryPoint>)
        .and()
        .exceptionHandling().accessDeniedHandler(<YOUR ACCESS DENIED HANDLER>);
    ...
  }

您的AccessDeniedHandler

@Override
  public void handle(HttpServletRequest request,
                     HttpServletResponse response,
                     AccessDeniedException accessDeniedException) throws IOException, ServletException {

    response.setHeader("Content-Type", "application/hal+json;charset=UTF-8");
    response.getOutputStream()
        .print(objectMapper
            .writeValueAsString("Access Denied");
    response.setStatus(403);
  }
© www.soinside.com 2019 - 2024. All rights reserved.