UserDetails,AuditorAware和JPA之间的交互

时间:2013-04-06 11:39:58

标签: spring spring-security spring-data spring-data-jpa

通过在Spring Roo / Hibernate中选择以下类层次结构 - JPA / Spring MVC / Spring Security应用程序,我可能使我的生活变得更加复杂:

DomainBase(审计字段 - 为lastUpdatedBy和createdBy字段引用AbstractUsers,因此循环依赖...(!))

@ManyToOne(fetch=FetchType.LAZY)
@CreatedBy
private AbstractUser createdBy;

@ManyToOne(fetch=FetchType.LAZY)
@LastModifiedBy
private AbstractUser lastModifiedBy;

^

|

AbstractUser(包含名称和字符串用户ID等一般用户信息)

@NotNull
@ManyToMany(fetch = FetchType.LAZY)
@Immutable
private Set<UserRole> roles;

^

|

运营商,消费者,客户(具体用户),系统用户

其他域类派生自DomainBase。

我使用审计员的以下实现:

public class SpringSecurityAuditorAware implements AuditorAware<AbstractUser> {

    public AbstractUser getCurrentAuditor() {

        Authentication authentication = SecurityContextHolder.getContext()
                .getAuthentication();

        return ((AbstractUser) authentication.getPrincipal());
    }
}

我对UserDetailsService的实现包含:

userDetails = operatorRepository.findByUsername(username);

if (userDetails != null) {
    // overcome lazy load
    Collection<? extends GrantedAuthority> roles = userDetails
            .getAuthorities();
    roles.size();
    return userDetails;
}

不幸的是,尽管尝试使用文档和谷歌,但JPA Transaction和Hibernate / JPA Session之间的关系仍然不清楚。在AuthenticationManager询问我的UserDetailsS​​ervice时,显然存在一个实时会话,并且返回的用户实体与持久性会话(实时)相关联,并且读取角色并用于确定以后的授权结果。在稍后的某个时间点,当用户发出涉及调用导致更改或创建新实体的@Transactional服务方法的请求时,AuditorAware<>侦听器将触发并分配存储在SecurityContext此对象,随后会保留。

我知道提出多个问题是不好的形式,但它们都与这个特定的安排相关。

1)更好的做法是将用户对象的深层副本存储在SecurityContext中,如果是这样,那么在审计员被解雇时获取“实时”实体的合理策略是什么?除了每次查询存储库外?)

2)我一般对处理域对象时持久化用户实体并不感兴趣,并尝试设置cascade=CascadeType.REFRESH但当然我在hibernate会话的上下文中遇到了用户对象是瞬态的。我想过只是将用户ID存储在DomainBase中,但是如果需要的话,我就失去了懒惰地获取用户详细信息的能力。我可以在这里找到“最佳实践”吗?

评论:对于试图同时与两个会话相关联的同一用户的用户角色集合,我似乎经常遇到麻烦(我有背景预定的工作,我怀疑我过度热心的日志记录{ {1}}可能与它有很多关系。)

任何指导赞赏......

0 个答案:

没有答案