我有一个Spring Boot应用程序,它有一个特殊要求,即用户(UserDetails
impls)需要拥有在经过身份验证后即时更改的角色/权限。
Spring Security是否允许这样做,或者我是否必须独立于Spring使用自己的角色/权限系统?
我对Spring Security的理解是UserDetails
impl在(成功)登录时加载一次,之后永远不会更新。但它必须可以动态更新用户/主体,用户在登录时如何编辑用户名或密码?所以我假设如果可以动态修改用户名/密码,那么角色和授权的权限(权限)也可以。
但是对于我的生活,我无法在网上任何地方找到这样的例子,也没有任何解释如何做到这一点的Javadocs。此外,这里是否会以任何方式涉及用户缓存(也就是Spring Security缓存用户,并且此缓存是否也需要更新)?
我最好的尝试是这样的:
// My UserDetailsService impl:
public class MyUserDetailsService implements UserDetailsService {
@Resource
private UserCache userCache;
// Lots of stuff up here
public void updateUserOnTheFly(UserUpdates userUpdates) {
MyUser user = (MyUser)SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
MyUserUpdater updater = new MyUserUpdater();
// Set new roles/permissions here, as well as (perhaps) other
// things.
updater.update(user, userUpdates); // I believe this updates the
// SecurityContext's Authentication instance
userCache.removeUserFromCache(user); // Necessary to first remove?
userCache.putUserInCache(user);
}
}
我是否在这里离开基地?
答案 0 :(得分:2)
通常,您不会在登录后更新角色。您在注册时分配特定角色。例如:
一旦用户成功登录,您就可以从UserDetails界面读取凭据。
但是可以做到。您的用户应该实现UserDetails接口
public class MyUser implements UserDetails { ... }
然后,当您从基于凭据的数据库中获取用户时,您可以更新角色/权限并返回该对象。
public class MyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
MyUser mu = customUserRepository.findByUsername(username);
List<Authority> authorityList = (List<Authority>) mu.getAuthorities();
authorityList.add(new Authority("ROLE_ON_THE_FLY"));
mu.setAuthorities(authorityList);
return mu;
}
class Authority implements GrantedAuthority {
private final String authority;
public Authority(String authority) {
this.authority = authority;
}
@Override
public String getAuthority() {
return authority;
}
}
}
希望它有所帮助。