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

时间:2011-02-04 16:05:34

标签: java hibernate spring spring-security

在我的自定义身份验证提供程序中,我能够通过我的Service 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 Security。

我想我可以创建一个特定的Service API来执行所有必需的检查,但我很好奇为什么我无法使用正确的事务包装我的自定义身份验证提供程序。

任何解释?感谢。

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

  

Spring抱怨Hibernate会话不存在

我不太确定我会回答你的所有问题,但我认为上述陈述代表了你的主要问题,对吧?你没有提供任何堆栈跟踪,但我想这是臭名昭着的“没有会话或会话关闭”,这是你刚刚描述的场景的典型:

  。

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

也许我错过了一些东西,但我认为典型的答案也适用于此:将您的关系映射到fetch=FetchType.EAGER,这样您就不必在会话已经关闭时延迟加载它。 / p>

答案 2 :(得分:0)

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

原因是因为在OpenSessionInView过滤器打开Hibernate会话之前调用了Spring Security,因此没有打开会话。

答案 3 :(得分:0)

您尚未发布任何可让我们提出任何有意义建议的代码。

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

例如 AbstractUserDetailsAuthenticationProvider 中的 retreiveUser 。从实例中调用此方法(请参阅方法 authenticate ),因此无法通过AOP代理机制初始化事务。有关详细信息,请查看@Transactional method calling another method without @Transactional anotation?

  

Spring声明式事务模型使用AOP代理。所以AOP代理负责创建交易。只有当实例中的方法从实例外部调用时,AOP代理才会处于活动状态。