spring-security - @Transactional 的 AOP 问题
问题描述
在我的 spring 5 MVC 应用程序中,我在调度程序 servlet xml 中使用<aop:aspectj-autoproxy />
. 控制器类的方法用@PreAuthorize("hasAuthority('SOME_AUTH')")
.
如果我启用 AOP,hasAuthority() 方法会调用数据库来检查权限。
如果我禁用 AOP,hasAuthority() 方法不会调用数据库来检查权限,而是从上下文本身检查权限。
(这是我通过在 TRACE 级别启用日志的观察结果。启用 AOP 后,我会看到用于检查控制台权限的查询。禁用 AOP 后,我看不到控制台上的查询。)
当 hasAuthority() 开始与数据库交互时,我必须注释控制器方法,@Transactional
以便关闭当前数据库会话。如果我不这样做,应用程序会在几次成功请求后停止工作,因为所有连接都被消耗,因为数据库会话没有关闭。
现在的问题是我不想with @PreAuthorize()
用@Transactional 注释控制器()的所有方法。此外,我不想将所有 hasAuthority() 方法移动到自定义 SecurityUtil 类,然后将 hasAuthority() 替换为@securityUtil.hasAuthority()
.
有没有其他方法可以在我的控制器方法上不使用@Transactional 来实现这一点,或者是否有某种方法可以强制 Spring Security 在启用 AOP 时从上下文而不是从数据库中检查权限?
更新
hasAuthority() 生成的查询如下:
select this_.type as y0_, this_.key_id as y1_ from permission_master this_ where this_.status=? and this_.key_id in()
SecurityExpressionRoot.java 类有方法 hasAuthority(),它依次调用以下方法: hasAuthority() -> hasAnyAuthority() -> hasAnyAuthorityName -> getAuthoritySet() -> roleHierarchy.getReachableGrantedAuthorities()
在我们的代码库中,调用 roleHierarchy.getReachableGrantedAuthorities() 被覆盖,因此我将 @Transactional 添加到覆盖调用并解决了我的问题。但我的问题是为什么启用 AOP 会使 hasAuthority() 调用数据库而禁用 AOP 不会。
解决方案
推荐阅读
- css - css中的中心条纹背景
- regex - In a Multi-columnar File - Remove all Trailing 0's from Decimal Numbers in Bash
- android - 更改材质导航视图中特定项目的背景颜色
- sqlite - 如何根据 Flutter 中的 ID 列表删除 SQLite 行?
- php - Laravel 7 - 嵌套资源路由中的范围问题
- python - 尝试从 S3 发送文件作为电子邮件附件时,字节类型的对象不是 JSON 可序列化的
- php - 如果值匹配,请在 php 中添加相关属性
- c# - 如何通过依赖注入将 UserManager 发送到 ASP.NET CORE 中的业务层?
- html - 多语言 Web 中的 lang html 标记
- c++ - crypto++ AES加密/解密对象重新初始化实践