java - Spring Security:如何在不登录和注销的情况下更改用户角色
问题描述
弹簧安全 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);
}
}
但是有一个麻烦。我需要为任何用户更改角色。假设我是经理,我想更改测试用户的角色。保存配置后我需要重新加载权限,当他按下 F5 按钮并重新加载页面而不重新登录时,测试用户将拥有新角色。但SecurityContextHolder.getContext().getAuthentication();
仅返回当前用户(经理)的身份验证对象。我需要获取身份验证对象以供更改的用户调用new
UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), actualAuthorities);
。我可以为任何用户获取身份验证对象,还是可以通过其他方式解决此问题?也许我可以让身份验证对象使用会话注册表?
PS:为用户做一个过期的会话不是一个好的选择。
解决方案
很好的答案,谢谢@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);
示例代码在 github 上提供:https ://github.com/aoa4eva/ContextDemo
推荐阅读
- python - 如何打印一次,直到 if 条件被打破?
- amazon-web-services - 在 IAM 政策中参考 AWS 帐号
- assembly - MASM 程序集库链接
- javascript - 不可见的 recaptcha v2 未检查必需的输入字段
- javascript - Uncaught TypeError: t.resolve is not a function ... polyfills
- vba - Excel VBA宏:以工作日频率自动填充列表
- java - Java-hot 只有一个按钮来回切换而不是两个按钮?
- node.js - Heroku / Node / React - 如何在 heroku 上访问我的节点 API 端点
- java - 如何匹配任何符号,包括行终止符?
- php - SQL error when running command from php file