在一个spring Boot 控制器中,我使用@PreAuthorize("isAuthenticated()")
来检查用户是否登录(使用基本auth + JSESSIONID
)。
但是如果用户没有登录,即他们没有经过身份验证,控制器将返回403 Forbidden
。
根据我所知道的身份验证与授权,401
用于身份验证,而403
用于授权。
根据我的理解,@PreAuthorize()
总是检查用户的授权(顾名思义),但是有没有什么方法可以根据我们传递给它的参数来定制它,比如这里的isAuthenticated()
?
我知道还有另一种解决方案:在configure(HttpSecurity httpSecurity)
中使用基于URL的安全配置,但如果我不想这样做呢?
任何想法请。
2条答案
按热度按时间q1qsirdb1#
当你用
@Pre/PostAuthorize
注解方法A时,spring将为这样的对象创建代理,并且每个对这样的方法的调用都将通过代理(如果对象在spring上下文下)。@Pre/PostAuthorize
的代理将从annotation中评估expression(这里很复杂),如果为true,则将请求父对象(传递给真实的方法),如果不为true,则抛出抛出DanieledException。您也可以在方法A中自己抛出这样的异常,效果也是一样的。这里讲的是@Pre/PostAuthorize
如何工作,没有更多的魔力!但这不是故事的结局!
如果
AccessDaniedException
没有被抑制或重新转换(没有堆栈,堆栈中没有AccessDaniedException
),那么它将被Spring Security中的ExceptionTranslationFilter
捕获,ExceptionTranslationFilter
将查看用户是否经过身份验证ExceptionTranslationFilter
将委托给AccessDeniedHandler
来处理这种情况,AccessDeniedHandler
的默认实现将返回403http代码或重定向到错误页面取决于您是否使用rest。ExceptionTranslationFilter
将委托给AuthenticationEntryPoint
,它将处理这种情况(重定向到登录页面,要求http基本.等)。注意:
ExceptionTranslationFilter
将重新抛出异常,如果任何其他AuthenticationException
或AccessDeniedException
和可能500将显示:(您的问题可能是另一个问题,请查看Spring Security anonymous 401 instead of 403
被抑制:(:
字符串
正确的重新翻译:):
型
epggiuax2#
我也遇到了同样的问题,我用
RestControllerAdvice
和ExceptionHandler
解决了这个问题字符串