Java 使用事务包装Spring安全自定义身份验证提供程序

Java 使用事务包装Spring安全自定义身份验证提供程序,java,hibernate,spring,spring-security,Java,Hibernate,Spring,Spring Security,在我的自定义身份验证提供程序中,我可以通过服务API获取域对象,但当我从一个域对象爬网到另一个域对象以获取特定值以执行附加检查时,Spring抱怨Hibernate会话不存在:- domain.getAnotherDomain().getProperty(); // epic FAIL 我有以下AOP事务来用事务包装我的所有项目API,我非常确定我的自定义身份验证提供程序属于以下模式:- <tx:advice id="txAdvice"> <tx:attributes

在我的自定义身份验证提供程序中,我可以通过服务API获取域对象,但当我从一个域对象爬网到另一个域对象以获取特定值以执行附加检查时,Spring抱怨Hibernate会话不存在:-

domain.getAnotherDomain().getProperty(); // epic FAIL
我有以下AOP事务来用事务包装我的所有项目API,我非常确定我的自定义身份验证提供程序属于以下模式:-

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor pointcut="execution(* my.project..*.*(..))" advice-ref="txAdvice" />
</aop:config>

我还配置了OpenSessionInView过滤器,但我认为这并不适用于Spring安全性

我想我可以创建一个特定的服务API来执行所有必需的检查,但是我很好奇为什么我不能用一个适当的事务包装我的自定义身份验证提供者

有什么解释吗?谢谢

Spring抱怨Hibernate会话不存在

我不太确定我是否完全理解你的问题,但我认为上述陈述代表了你的主要问题,对吗?您没有提供任何stacktrace,但我认为这是臭名昭著的“无会话或会话关闭”,这是您刚才描述的典型场景:

domain.getAnotherDomain().getProperty();//史诗般的失败


也许我遗漏了什么,但我认为典型的答案也适用于这里:映射您与
fetch=FetchType.EAGER的关系,这样,您就不必在会话已关闭时延迟加载它。

我的解决方案是创建一个服务API来执行检查,以避免在自定义身份验证提供程序中延迟加载错误。

我遇到了同样的问题,原因是我在web.xml文件中的
OpenSessionInView
过滤器之前声明了Spring Security的过滤器。一旦我换了它们,问题就消失了


原因是因为Spring Security在Hibernate会话被
OpenSessionInView
筛选器打开之前被调用,因此没有打开任何会话。

您没有发布任何代码,让我们可以执行任何有意义的建议

但是,自定义身份验证提供程序的一个问题可能是,您可能会将一个抽象方法标记为@Transactional,您正在重写该抽象方法,并从抽象类实例调用该抽象方法

例如,AbstractUserDetailsAuthenticationProvider检索用户。此方法是从实例内部调用的(请参见方法验证),因此无法通过AOP代理机制初始化事务。有关更多详细信息,请查看

Spring声明性事务模型使用AOP代理。因此,AOP代理负责创建事务。只有从实例外部调用实例中具有的方法时,AOP代理才会处于活动状态


异常消息是
未能延迟初始化角色集合:ss.domain,没有会话或会话已关闭
。除非绝对必要,否则我宁愿不执行即时抓取。。。也就是说,如果我让事务包装自定义身份验证提供程序类。那么,如果您在一个会话中加载了
,那么您将无法在另一个会话中从
惰性地加载另一个域
。不过,我不确定这是否是你的情况(从你的问题来看,我不清楚)。但是如果你不想总是急于加载,你可以考虑使用FEXCH配置文件,但是你知道有时候你需要。