Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring安全性:如何在不登录和注销的情况下更改用户角色_Java_Spring_Security_Authentication - Fatal编程技术网

Java Spring安全性:如何在不登录和注销的情况下更改用户角色

Java Spring安全性:如何在不登录和注销的情况下更改用户角色,java,spring,security,authentication,Java,Spring,Security,Authentication,弹簧安全4.2.4。爪哇8 我需要更改用户的权限,而无需重新记录它们。这是我的服务: @Component public class AuthoritiesUpdater { private final UserRoleService userRoleService; @Autowired public AuthoritiesUpdater(UserRoleService userRoleService) { this.userRoleService

弹簧安全4.2.4。爪哇8

我需要更改用户的权限,而无需重新记录它们。这是我的服务:

@Component
public class AuthoritiesUpdater {

    private final UserRoleService userRoleService;

    @Autowired
    public AuthoritiesUpdater(UserRoleService userRoleService) {
        this.userRoleService = userRoleService;
    }

    public void update(User user) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        List<UserRole> userRoles = userRoleService.findByUser(user);

        List<GrantedAuthority> actualAuthorities = userRoles.stream().map(userRole -> new 
SimpleGrantedAuthority(userRole.getRole())).collect(Collectors.toList());

        Authentication newAuth = new 
UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), actualAuthorities);

        SecurityContextHolder.getContext().setAuthentication(newAuth);
    }
}
@组件
公共类AuthoritiesUpdater{
专用最终用户角色服务用户角色服务;
@自动连线
公共机构更新程序(UserRoleService UserRoleService){
this.userRoleService=userRoleService;
}
公共无效更新(用户){
Authentication auth=SecurityContextHolder.getContext().getAuthentication();
List userRoles=userroleseservice.findByUser(用户);
列出actualAuthorities=userRoles.stream().map(userRole->new
SimpleGrantedAuthority(userRole.getRole()).collect(Collectors.toList());
身份验证newAuth=new
UsernamePasswordAuthenticationToken(auth.getPrincipal()、auth.getCredentials()、actualAuthorities);
SecurityContextHolder.getContext().setAuthentication(newAuth);
}
}
但是有一个麻烦。我需要为任何用户更改角色。假设我是经理,我想更改测试用户的角色。我需要在保存配置后重新加载权限,当测试用户按F5按钮并重新加载页面而不重新登录时,他将拥有新角色。 但是
SecurityContextHolder.getContext().getAuthentication()仅返回当前用户(管理器)的身份验证对象。我需要为更改的用户获取身份验证对象以调用
new
UsernamePasswordAuthenticationToken(auth.getPrincipal()、auth.getCredentials()、actualAuthorities)。
我可以为任何用户获取身份验证对象吗?或者我可以用另一种方法解决此问题吗?也许我可以使用会话注册表获取身份验证对象


备注:为用户执行过期会话不是一个好选择。

解决方案比我想象的要简单一些。我有一个用户。 我可以调用
UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword(),actualAuthorities)
而不是
UsernamePasswordAuthenticationToken(auth.getPrincipal()、auth.getCredentials()、actualAuthorities)。
我不需要获取身份验证对象。服务的最终版本:

@Component
public class AuthoritiesUpdater {

    private final UserRoleService userRoleService;

    @Autowired
    public AuthoritiesUpdater(UserRoleService userRoleService) {
        this.userRoleService = userRoleService;
    }

    public void update(User user) {
        List<UserRole> userRoles = userRoleService.findByUser(user);

        List<GrantedAuthority> actualAuthorities = userRoles.stream().map(userRole -> new SimpleGrantedAuthority(userRole.getRole())).collect(Collectors.toList());

        Authentication newAuth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), actualAuthorities);

        SecurityContextHolder.getContext().setAuthentication(newAuth);
    }
}
@组件
公共类AuthoritiesUpdater{
专用最终用户角色服务用户角色服务;
@自动连线
公共机构更新程序(UserRoleService UserRoleService){
this.userRoleService=userRoleService;
}
公共无效更新(用户){
List userRoles=userroleseservice.findByUser(用户);
List actualAuthorities=userRoles.stream().map(userRole->new simplegrantedoauthority(userRole.getRole()).collect(Collectors.toList());
Authentication newAuth=新用户名PasswordAuthenticationToken(user.getUsername(),user.getPassword(),actualAuthorities);
SecurityContextHolder.getContext().setAuthentication(newAuth);
}
}

回答得很好,谢谢@virkom

对于较新的用户,步骤如下:

  • 创建您希望用户拥有的权限列表(包括他们以前拥有的权限)。在本例中(如下),我创建了一个集合,以便它们是唯一的

  • 创建一个身份验证对象,该对象与要向其新权限进行身份验证的用户相匹配。在本例中,我使用了一个在内存中的用户来简化示例,但首选数据库身份验证

  • 使用新的身份验证信息更新安全上下文。这将具有刷新用户凭据的效果

  • 代码片段如下所示:

    Set<GrantedAuthority> authorities = new HashSet<>();
    authorities.add(new SimpleGrantedAuthority("USER"));
    authorities.add(new SimpleGrantedAuthority("ADMIN"));
    
    Authentication reAuth = new UsernamePasswordAuthenticationToken("user",new 
    
    BCryptPasswordEncoder().encode("password"),authorities);  
    
    SecurityContextHolder.getContext().setAuthentication(reAuth);
    
    Set authorities=new HashSet();
    添加(新的SimpleGrantedAuthority(“用户”);
    添加(新的SimpleGrantedAuthority(“管理”);
    Authentication reAuth=新用户名PasswordAuthenticationToken(“用户”,新
    BCryptPasswordEncoder().encode(“密码”),权限;
    SecurityContextHolder.getContext().setAuthentication(重新授权);
    

    github上提供了示例代码:

    不是同一个问题,但可能也是一个适用于您的用例的答案: