在我的Spring 5 MVC应用程序中,我已经使用<aop:aspectj-autoproxy />
在调度程序servlet xml中启用了AOP。
控制器类的方法用@PreAuthorize("hasAuthority('SOME_AUTH')")
注释。
如果启用AOP,则hasAuthority()方法将调用数据库以检查权限。
如果禁用AOP,则hasAuthority()方法不会调用数据库来检查权限,而是从上下文本身检查权限。
(这是我在TRACE级别上启用日志的观察结果。启用AOP后,我会在控制台上看到查询以检查权限。禁用AOP后,我的控制台上不会看到查询。)
当hasAuthority()开始与数据库交互时,我必须用@Transactional
注释控制器方法,以便关闭当前数据库会话。如果我不这样做,那么应用程序会在几次成功请求后停止工作,因为所有连接都被消耗了,因为未关闭数据库会话。
现在的问题是,我不想使用@Transactional注释控制器(with @PreAuthorize()
)的所有方法。
另外,我不想将所有的hasAuthority()方法移至自定义的SecurityUtil类,然后用@securityUtil.hasAuthority()
替换hasAuthority()。
是否有其他方法可以在不使用控制器方法上使用@Transactional的情况下实现此目的,或者是否有某种方法可以强制Spring Security在启用AOP时从上下文而不是从数据库检查权限? / p>
更新
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却没有。