当前位置: 首页 > 知识库问答 >
问题:

spring安全中的角色与授权的区别

师成弘
2023-03-14

spring安全中有一些概念和实现,例如grantedauthority接口,用于获取授权/控制访问的权限。

我希望允许的操作,如createSubUsers或deleteAccounts,我允许管理员(使用角色role_admin)执行这些操作。

当我在网上看到教程/演示时,我感到很困惑。我试着把我读到的东西联系起来,但我认为我们可以互换地对待这两者。

我看到HasRole使用GrantedAuthority字符串?我绝对是在理解上做错了。这些在spring安全概念上是什么?

如何将用户的角色与该角色的权限分开存储?

我还查看了org.springframework.security.core.userdetails.userdetails接口,该接口用于引用身份验证提供程序的DAO中,该DAO使用user(注意last GrantedAuthority):

public User(String username, 
            String password, 
            boolean enabled, 
            boolean accountNonExpired,
            boolean credentialsNonExpired, 
            boolean accountNonLocked, 
            Collection<? extends GrantedAuthority> authorities)

或者有没有其他的方法来区分另外两个呢?还是不支持,要自己做?

共有1个答案

罗祺
2023-03-14

把GrantedAuthority看作是“许可”或“权利”。这些“权限”(通常)被表示为字符串(使用getAuthority()方法)。这些字符串允许您标识权限,并允许您的投票人决定是否授予对某些内容的访问权限。

您可以通过将用户放入安全上下文中,向用户授予不同的GrantedAuthoritys(权限)。通常通过实现自己的UserDetailsService来实现,该Service返回一个UserDetails实现,该实现返回所需的GrantedAuthorities。

角色(在许多示例中使用它们)只是“权限”,其命名约定规定角色是以前缀role_开头的GrantedAuthority。没有别的了。角色只是一个GrantedAuthority--一个“许可”--一个“权利”。您可以在spring安全中看到许多地方,使用role_前缀的角色被特别地处理为,例如在RoleVoter中,使用role_前缀作为默认值。这允许您提供不带role_前缀的角色名称。在spring security 4之前,对“角色”的这种特殊处理没有得到非常一致的遵循,权限和角色的处理通常是相同的(例如,您可以在SecurityExpressionRoot中的HasAuthority()方法的实现中看到-它只是调用HasRole())。在spring安全4中,角色的处理更加一致,处理“角色”的代码(如RoleVoterHasRole表达式等)总是为您添加Role_前缀。因此hasauthority('role_admin')hasrole('admin')意思相同,因为role_前缀是自动添加的。有关更多信息,请参阅《spring安全3到4迁移指南》。

但仍然是:角色只是具有特殊role_前缀的权威。因此,在spring安全3中,@preauthorize(“HasRole('Role_XYZ')”)@preauthorize(“HasAuthorize('Role_XYZ')”)相同,在spring安全4中,@preauthorize(“HasRole('XYZ')”)@preauthorize(“HasAuthorize('Role_XYZ')”相同。

关于您的用例:

用户有角色,角色可以执行某些操作。

您可以在grantedauthorities中结束用户所属的角色和角色可以执行的操作。角色的GrantedAuthorities具有前缀Role_,操作具有前缀OP_。操作权限的示例可以是op_delete_accountop_create_userop_run_batch_job等。角色可以是role_adminrole_userrole_owner等。

您可以最终让您的实体实现grantedauthority,如下(伪代码示例所示:

@Entity
class Role implements GrantedAuthority {
    @Id
    private String id;

    @ManyToMany
    private final List<Operation> allowedOperations = new ArrayList<>();

    @Override
    public String getAuthority() {
        return id;
    }

    public Collection<GrantedAuthority> getAllowedOperations() {
        return allowedOperations;
    }
}

@Entity
class User {
    @Id
    private String id;

    @ManyToMany
    private final List<Role> roles = new ArrayList<>();

    public Collection<Role> getRoles() {
        return roles;
    }
}

@Entity
class Operation implements GrantedAuthority {
    @Id
    private String id;

    @Override
    public String getAuthority() {
        return id;
    }
}

在数据库中创建的角色和操作的ID将是GrantedAuthority表示形式,例如role_adminop_delete_account等。当对用户进行身份验证时,请确保从userDetails.getAuthorities()方法返回其所有角色和相应操作的所有GrantedAuthorities。

示例:id为role_admin的admin角色分配了op_delete_accountop_read_accountop_run_batch_job操作。id为role_user的用户角色具有op_read_account操作。

如果管理员登录到生成的安全上下文中,则将具有授予的权限:role_adminop_delete_accountop_read_accountop_run_batch_job

如果用户记录它,它将具有:role_userop_read_account

UserDetailsService将注意收集所有角色和这些角色的所有操作,并通过返回的UserDetails实例中的方法getAuthorities()使它们可用。

 类似资料:
  • 我正在试图理解一些Spring Security代码。我也是Spring Security的新手,我想我在这里遗漏了一些基本的东西。 谢谢,雷。

  • 我对Spring靴还不熟悉。我需要在spring boot中实现基于角色的授权。我有不同的角色,多个用户将映射到每个角色。每当调用api时,我都会设置不同的访问权限(读取、添加、删除、编辑),需要检查访问权限并允许权限。我计划使用拦截器调用具有查询的方法,以从DB获取访问权限,并拒绝或访问api。有没有其他更好的方法我可以用同样的方法?

  • Using a delegation key The collaborator can now push to the repository using Docker Content Trust. Docker will automatically choose and pick the right key for the targets/release role. Edit the file o

  • Importing a delegation certificate As a repository owner: Add the delegation key to the repository using the targets/releases path, as this is what Docker searches for when signing an image (first tar

  • Generating a delegation key Make sure you’re using OpenSSL 1.0.2+, otherwise the keys will be signed with SHA1, which Notary will refuse to import (invalid SHA1 signature algorithm): ❯ brew install op

  • VS2013,MVC5 我可能会弄错一些术语,因为我是这个主题的新手。 我所读到的让我得出结论,声明可以用于身份验证和授权,这是两个非常不同的概念。假设这种想法是正确的,我的问题与声明有关,因为它们可能适用于授权,而不是身份验证(或身份?-将身份视为身份验证的替代概念准确吗?) 维基百科的文章似乎和我读到的其他任何东西一样简洁,说(最后一节第一行)声明和角色之间的区别是: 如果我使用声明来决定一个