【问题标题】:Custom User, roles, permissions implementing UserDetail and UserDetailService with Spring Security使用 Spring Security 实现 UserDetails 和 UserDetailSservice 的自定义用户、角色、权限
【发布时间】:2020-10-14 18:07:25
【问题描述】:

我希望使用带有 MySql 的 Spring Security 来存储用户、角色、权限(权限)。我做了以下事情:

ApplicationUser(id、firstName、lastName、用户名、密码、角色
ApplicationRole(id、名称、描述、权限)实现 GrantedAuthority
ApplicationPermission(id, name, description) 实现 GrantedAuthority

我创建了一个实现 UserDetailService 的类。在 loadUserByUsername 方法中,我执行以下操作:

ApplicationUser applicationUser = userRepository.findByUsername(username);
if(applicationUser == null) {
    throw new UsernameNotFoundException(username);
}

// Extract role/role permission grantedAuthorities from db user
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (Role role: applicationUser.getRoles()) {
    grantedAuthorities.add(role);
    grantedAuthorities.addAll(role.getPermissions());
}

return new User(applicationUser.getUsername(), applicationUser.getPassword(), grantedAuthorities);

但是,这仍然让我有点困惑,这里有一些我的问题......

  1. 是否有必要在我的 ApplicationRole 上实现 GrantedAuthority 和 ApplicationPermission 类。我没有看到其他人在很多地方这样做 我见过的例子,但它似乎让我的生活更轻松 这样我就可以得到它们并按原样传递它们。
  2. 我没有 用我的 ApplicationUser 类实现了 UserDetails。如果我要 这样做的目的是什么?是唯一的原因,所以我会 能够自定义 getAuthorities、isAccountNonExpired、 isAccountNonLocked、isCredentialsNonExpired、isEnabled 方法?是 甚至有这些方法的默认实现,或者只有当我 创建我的版本。为什么我需要实现 getAuthorities 如果我已经在使用 loadbyUserName 执行此操作 UserDetailsS​​erviceImpl?
  3. SimpleGrantedAuthority 的用途是什么?我看到它实现了 GrantedAuthority 并且只接受一个字符串名称。但是,我觉得我不需要使用它,因为我使用我的 ApplicationRole 和 ApplicationPermission 类实现了 GrantedAuthority。

我认为我的问题是我对何时/如何正确实施 UserDetail 和 UserDetailService 感到困惑,以确保我从数据库中加载权限并在每次用户登录时设置它们。此外,是否有任何意义以我的方式使用我的 ApplicationRole 和 ApplicationPermission 类实现 GrantedAuthority?

【问题讨论】:

    标签: java spring spring-boot spring-security


    【解决方案1】:
    1. 这不是必需的,我也不推荐它。最好将应用程序的这些不同方面分开。据我所知,在您的自定义UserDetailsService 中获取角色并将其文本表示形式包装在SimpleGrantedAuthority(即他们的名字)中是一种常见的做法。请注意,要区分 Spring Security 中的角色和权限,您必须默认为角色添加 ROLE_ 标签前缀(请参阅 hasRolehasAuthority 访问控制表达式)。

    2. 自定义UserDetails 实现不是必需的,但可能有好处,例如您可以存储特定于您的应用程序的额外字段。默认实现是org.springframework.security.core.userdetails.User,大多数时候你可以扩展这个。

    3. 参见#1

    以我的方式使用我的 ApplicationRole 和 ApplicationPermission 类实现 GrantedAuthority 有什么意义吗?

    这没有任何意义,不。现有实现涵盖了许多用例,但对于最简单的用例,您可以坚持使用SimpleGrantedAuthority

    【讨论】:

    • 非常感谢。我的最终目标是仅在必要时实现/覆盖或扩展。我的主要关注点如下: 1. 拥有我自己的包含自定义属性的角色类。 2. 拥有我自己的包含自定义属性的 Permission 类。 3. 拥有一个包含自定义属性的 User 类,并适合 Spring 安全性的其余部分。能够将所有内容持久保存到 MySql 数据库(包括属于 UserDetails 实体的标志)。你能告诉我是否还有什么需要知道的以使这项工作尽可能干净吗?
    • 除了我上面所说的之外,还有我的计划:拥有不实现任何东西的 ApplicationRole 和 ApplicationPermission 类。我的 ApplicationUser 类可以扩展 UserDetails.User 而不是实现 UserDetails (除非我真的需要覆盖其中一种方法中的逻辑)。然后最后创建覆盖 loadUserByUsername 方法的 UserDetailsS​​ervice 的自定义实现,确保我通过用户名从数据库中检索用户,然后将 SimpleGrantedAuthorities 发送到 userdetails。用户返回值。有什么我可能遗漏的吗?
    • 从你所说的我会说你得到了它几乎覆盖。尽量让它尽可能简单,只有在你认为确实有必要时才创建自​​定义实现。
    猜你喜欢
    • 2019-08-22
    • 2014-11-21
    • 2010-11-02
    • 2022-08-09
    • 2011-07-21
    • 2012-01-29
    • 2016-04-27
    • 2016-02-27
    • 2019-08-06
    相关资源
    最近更新 更多