【问题标题】:Spring Security endpoint protection by dynamic roles动态角色的 Spring Security 端点保护
【发布时间】:2018-03-13 11:28:00
【问题描述】:

对通过用户角色保护端点有疑问。我有一个端点“/message”,它以如下所示的两种方式之一受到保护

1) 在Controller中如下

@PreAuthorize("hasAuthority('USER')")
@RequestMapping(value = "/message", method = RequestMethod.GET)
public String message() {
    return "Hello World!!!"
}

2)在配置(WebSecurityConfigurereAdapter)文件中如下

@Override
public void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests().anyRequest().authenticated()
        .antMatchers(HttpMethod.GET, "/message").access("hasAuthority('USER')");
}

可以看出角色 USER 已经被两种方式硬编码,如何动态实现,一种方式是我们可以从配置文件中的数据库中读取并构建 HttpSecurity,但这发生在应用程序启动期间,在运行时创建的新角色如何保护端点?

【问题讨论】:

  • 你必须实现 PermissionEvaluator 和 example:

标签: spring-boot spring-security


【解决方案1】:

保护可随时更改的端点的最佳方式:

如果您想授予/撤销用户的角色/权限,最好的方法是使用权限而不是角色。在这种情况下,每个用户将只有一个角色。每个角色都可能有一个权限列表,可以随时使用 UI 从角色中添加/删除。

怎么办?

public class Privilege{
    @Id
    private String id;
    private String name;

    //Constructors +  Getters & Setters
}

public class Role{

    @Id
    private String id;
    private String name;
    private List<Privilege> privileges;

    //Constructors +  Getters & Setters
}

public class MyUser{
    private Role role;
    //All Required params
    //Constructors +  Getters & Setters
}

public class MyUserDetailsService implements UserDetailsService{
    public User loadUserByUsername(final String userId) {
        User user = //load your user
        Role role = //load above user role
        Collection<GrantedAuthority> grantedAuthorities.add(new SimpleGrantedAuthority(merchantRole.getName()));

        for(Privilege privilege : role.getPrivileges()){
            grantedAuthorities.add(new SimpleGrantedAuthority(privilege.getName()));
        }

        return new User(username, password, grantedAuthorities);
    }
}

最后你的配置文件应该是这样的:

@Override
public void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests().anyRequest().authenticated()
        .antMatchers(HttpMethod.GET, "/message").access("hasAuthority('YOUR_PRIVILAGE')");
}

注意

尝试创建尽可能不可分割的权限。意思是说每个特权应该特定于每个特定任务。因此,任何时候都可以使用任何权限组合创建任何角色,而无需更改 antMatchers/security。

例子:

CREATE_USER_PRIVILEGE
UPDATE_USER_PRIVILEGE
DELETE_USER_PRIVILEGE
VIEW_USER_PRIVILEGE

等等

ADMIN_ROLE = {CREATE_USER_PRIVILEGE, UPDATE_USER_PRIVILEGE, DELETE_USER_PRIVILEGE, VIEW_USER_PRIVILEGE}
ADMIN_ROLE = {VIEW_USER_PRIVILEGE}

等等

【讨论】:

    猜你喜欢
    • 2011-07-14
    • 2016-03-04
    • 1970-01-01
    • 2020-04-11
    • 2020-01-31
    • 2020-12-20
    • 2017-05-18
    • 1970-01-01
    • 2019-06-19
    相关资源
    最近更新 更多