成功登录后如何更新 Spring Security UserDetails impls?

Posted

技术标签:

【中文标题】成功登录后如何更新 Spring Security UserDetails impls?【英文标题】:How to update Spring Security UserDetails impls after successful login? 【发布时间】:2016-10-03 04:46:27 【问题描述】:

我有一个 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);
    

我是在轨道上还是离基地很远?

【问题讨论】:

【参考方案1】:

通常您不会在登录后更新角色。您在注册时分配特定角色。例如:

未登录(未经授权) 已登录 (ROLE_USER) 某些特定的登录用户,您手动或基于某些逻辑 (ROLE_ADMIN) 分配 ...

一旦用户成功登录,您就可以从 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;
    


希望对你有帮助。

【讨论】:

以上是关于成功登录后如何更新 Spring Security UserDetails impls?的主要内容,如果未能解决你的问题,请参考以下文章

成功登录后如何更新 Spring Security UserDetails impls?

使用spring security成功登录后如何将对象添加到视图中?

使用 Spring Security 成功登录后如何将用户转发回所需的受保护页面

登录后spring security重定向不正确

登录 Spring Security 后如何返回基本令牌?

Spring Security中如何防止多次登录