繁体   English   中英

Spring Security:安全性过滤器中引发的异常映射

[英]Spring Security: mapping of exceptions thrown inside security filter

我有自定义的安全筛选器,可以用作其他授权步骤。

筛选器检查是否可以授权用户,如果不应该访问该用户,则引发异常。

问题是, 如果我从过滤器中抛出异常则该异常不会被映射到正确的状态代码 (在我的情况下,我需要HTTP 403)。

我不能使用@ControllerAdvice@ExceptionHandler因为安全过滤器在处理控制器之前起作用

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

问:有什么方法可以自动将异常从过滤器映射到正确的状态代码? 还是有没有办法实现过滤器而没有例外?

注意:我也阅读了这篇文章 ,但是从调试中我看到我的过滤器链不包含ExceptionTranslationFilter

还是有没有办法实现过滤器而没有例外?

显然,您可以直接写入响应并从遇到身份验证或授权失败的那一刻起返回。 抛出异常然后进行全局处理对我来说似乎是不必要的过度工作,因为我只有一个JWT身份验证过滤器实现-AbstractAuthenticationProcessingFilter

每当认证条件不能满足,像JWT令牌解析问题,缺少令牌,令牌畸形等,我只需登录错误,设定HttpStatus并返回nullattemptAuthentication方法。

这样,我的整个逻辑就封装在单个类中。 我还必须在所有情况下都发送401 ,但错误消息有所不同,这是通过简单的实用程序方法处理的。

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

Spring推荐的方法是拥有一个实现AccessDeniedHandler@Component ,然后在扩展WebSecurityConfigurerAdapter的类WebSecurityConfigurerAdapter注册到configure(HttpSecurity ...)方法中的.accessDeniedHandler()中。 那是针对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);
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM