Spring Security 有一个代表经过身份验证的用户的基类(org.springframework.security.core.userdetails.User
):
Models core user information retrieved by a UserDetailsService.
Developers may use this class directly, subclass it, or write their own UserDetails implementation from scratch.
在互联网上的大多数示例中,例如 here人们通常为持久性创建单独的类,即示例中的 com.mkyong.users.model.User
。
这个类没有扩展 spring security 的,所以现在我们有两个用户,一个用于持久化,一个代表系统中经过身份验证的用户,我们所做的一切是:
- 通过用户名和密码检索持久性用户
- 将字段复制到 spring User 并返回
那么,我的问题是,再拥有一个 User 对象有什么意义呢?扩展 spring security User 并持久化它不是更好吗? hibernate/jpa 注释可能无法实现,因为我们显然不能在 spring 安全代码中放置注释,但是它可以通过映射文件来实现。这里的另一个问题是我们不应该从服务返回 hibernate 实体以避免服务层外的所有 hibernate 相关问题,所以如果我扩展 spring User 并使它成为一个实体,我无论如何都需要某种 POJO 来从 UserDetailsService
返回。这就是我们需要两个用户对象的原因吗?
附言感谢引用文档
最佳答案
主要原因是:
- 关注点分离
- 单一职责原则
UserDetails
旨在公开有关经过身份验证的用户的特定信息,因为它与 Spring Security 相关。这是一个可以在任何版本中根据该项目的需要进行更改的类。
通过扩展该类并允许您的持久性模型基于它,您现在可以强制您的持久性模型在任何时候被这些更改所挟持。你不可避免地违反了这两个原则。
使用单独的持久性类的好处是,您现在可以自由地将安全属性存储在适合应用程序需求和目标的任何数据模型中。此外,您的数据库架构不再受您无法控制的外部更改的约束。
这正是 Spring Security 公开 UserDetailsService
的原因。该服务接口(interface)旨在允许 Spring Security 调用特定的存储库实现并将您的持久性模型转换为框架所需的必要 UserDetails
实现,而不会违反上述两个原则。
关于java - 坚持 org.springframework.security.core.userdetails.User 或 UserDetails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42314725/