持久化 org.springframework.security.core.userdetails.User 或 UserDetails

5
Spring security有一个基类表示已认证的用户(org.springframework.security.core.userdetails.User):

由UserDetailsService检索的核心用户信息模型。开发人员可以直接使用此类,子类化它或从头编写自己的UserDetails实现。

在大多数互联网示例中,例如这里,人们通常为持久性创建单独的类,例如该示例中的com.mkyong.users.model.User。该类不扩展spring安全性,因此现在我们有两个用户,一个用于持久化,另一个表示系统中经过身份验证的用户,我们所做的一切是:
  1. 通过用户名和密码检索持久性用户
  2. 将字段复制到spring用户并返回它
那么,我的问题是,拥有另一个用户对象的意义何在?是否将spring security User扩展并进行持久化会更好?在hibernate / jpa注释中可能不可行,因为我们显然无法在spring security代码中放置注释,但是可以通过映射文件完成。这里的另一个问题是,我们不应该从服务返回hibernate实体,以避免所有服务层外的与hibernate相关的问题,因此如果我扩展spring User并将其作为实体,我仍然需要某种POJO从UserDetailsService返回。如果是这种情况,那么我们需要两个用户对象吗?
附:文档的参考资料将不胜感激。

你的模型应该与你使用的库解耦。考虑到新的开发经理想要将项目从Spring转移到EJB,那么你就不需要改变所有的东西(pojo、dao、service...)。 - Comfort Chauke
1个回答

3
主要原因如下:
  • 关注点分离
  • 单一职责原则
UserDetails旨在作为Spring Security中与经过身份验证的用户相关的特定信息公开。这是一个可以根据项目需要在任何发布时更改的类。
通过扩展该类并允许您的持久性模型基于它,现在您会发现您的持久性模型会被拘为人质在任何时候进行更改。这违反了两个原则。
使用单独的持久性类的好处是您现在可以自由地将安全属性存储在适合您应用程序需求和目标的任何数据模型中。此外,您的数据库架构不再受到您无法控制的外部更改的约束。
这正是为什么Spring Security会公开UserDetailsService。该服务接口旨在允许Spring Security调用特定的存储库实现,并将您的持久性模型转换为框架需要的必要的UserDetails实现,而不违反上述两个原则。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接