【问题标题】:How to customize the http status returned by @PreAuthorize("isAuthenticated()")?如何自定义@PreAuthorize("isAuthenticated()") 返回的http状态?
【发布时间】:2019-09-01 17:13:48
【问题描述】:

在 Spring Boot 控制器中,我使用 @PreAuthorize("isAuthenticated()") 检查用户是否已登录(使用基本身份验证 + JSESSIONID)。
但是如果用户没有登录,即他们没有通过身份验证,控制器会返回403 Forbidden。
根据我对身份验证与授权的了解,401 用于身份验证,而403 用于授权。

据我了解@PreAuthorize() 总是检查用户的授权(顾名思义),但是有没有办法根据我们传递给它的参数来定制它,即isAuthenticated() 这里?

我知道还有另一种解决方案:在configure(HttpSecurity httpSecurity) 中使用基于 URL 的安全配置,但如果我不想这样做怎么办。

请有任何想法。

【问题讨论】:

    标签: spring-boot spring-security


    【解决方案1】:

    当您使用 @Pre/PostAuthorize 注释方法 A 时,spring 将为此类对象创建代理,并且对此类方法的每次调用都将通过代理(如果对象在 spring 上下文中)。

    @Pre/PostAuthorize 的代理将评估来自注解的表达式(这里很复杂),如果它是真的,那么如果不是throw AccessDaniedException,则传递请求父亲(到真正的方法)。你也可以在你的方法A中自己抛出这样的异常,效果是一样的。这一切都与@Pre/PostAuthorize 在这里不再有魔力有关!

    但这并不是故事的结局!

    如果AccessDaniedException 未被抑制或重新翻译(没有没有AccessDaniedException 的堆栈),它将被Spring Security 中的ExceptionTranslationFilter 捕获,ExceptionTranslationFilter 将查看用户是否已通过身份验证

    • 如果是,则ExceptionTranslationFilter 将委托给AccessDeniedHandler 处理这种情况,AccessDeniedHandler 的默认实现将返回 403 http 代码或重定向到 错误页面 取决于您是否使用休息。

    • 如果不是,ExceptionTranslationFilter 将委托给AuthenticationEntryPoint,它会处理这种情况(重定向到登录页面,请求 http 基本 ... 等)。

    注意:ExceptionTranslationFilter 将重新抛出除 AuthenticationException 或 AccessDeniedException 以外的任何异常,并且可能会显示 500 :(

    你的问题可能是另一个问题看看Spring Security anonymous 401 instead of 403

    抑制:(:

        @GetMapping(value = "/test/ok")
        public String getOk() {
            try {
                myService.securedMethod();
                return "ok";
            } catch (Exception e) {
                log.info("AccessDeniedException suppressed not rethrowing :(", e);
                return "error";
            }
        }
    

    正确的重新翻译:):

        @GetMapping(value = "/test/ok")
        public String getOk() {
            try {
                myService.securedMethod();
                return "ok";
            } catch (AccessDeniedException e) {
                throw new MyException(e); //public MyException(Throwable cause)
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多