You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebFlux Security 如何在会话中更新认证信息无需重新登录

问题原因

你之前使用ReactiveSecurityContextHolder.withAuthentication(authentication)的方式仅将认证信息写入了当前请求的订阅上下文,只对单次请求生效,不会持久化到WebSession中,所以后续请求获取到的还是旧的用户信息。

正确实现方案

你配置的安全上下文是存储在WebSession中,只需要调用你自定义注册的ServerSecurityContextRepository的save方法,将更新后的安全上下文写入当前会话即可,完整实现步骤如下:

  1. 首先注入你在配置类中声明的ServerSecurityContextRepository实例
@Autowired
private ServerSecurityContextRepository securityContextRepository;
  1. 在更新用户信息的业务逻辑中,构造更新后的认证信息并写入会话,代码示例如下(以Controller接口为例):
@PutMapping("/api/v1/user/update-info")
public Mono<Void> updateUserInfo(@RequestBody UserUpdateDTO updateDTO, ServerWebExchange exchange) {
    return ReactiveSecurityContextHolder.getContext()
            .map(SecurityContext::getAuthentication)
            .flatMap(oldAuth -> {
                // 构造更新后的用户信息,替换为你的实际业务逻辑
                MyAppUserDetails updatedUser = new MyAppUserDetails(
                        updateDTO.getFirstName(),
                        updateDTO.getLastName(),
                        updateDTO.getEmail(),
                        // 保留原有用户ID、组织ID等不可修改的属性,或者按需求更新
                        ((MyAppUserDetails) oldAuth.getPrincipal()).getUserId(),
                        ((MyAppUserDetails) oldAuth.getPrincipal()).getOrgId()
                );
                
                // 构造新的认证凭证,注意必须传入用户权限集合,否则会被判定为未认证
                // 凭证可以复用原有凭证,不需要修改的话直接传入oldAuth.getCredentials()即可
                UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(
                        updatedUser,
                        oldAuth.getCredentials(),
                        // 如果更新了用户权限,这里传入新的权限集合即可
                        oldAuth.getAuthorities()
                );
                
                // 构造新的安全上下文
                SecurityContext newSecurityContext = new SecurityContextImpl(newAuth);
                
                // 将新的安全上下文保存到当前会话中
                return securityContextRepository.save(exchange, newSecurityContext);
            });
}

注意事项

  • securityContextRepository.save返回的是Mono<Void>,必须将其加入响应式流的订阅链,不能单独调用否则该操作不会执行,更新不会生效
  • 构造新的UsernamePasswordAuthenticationToken时必须传入第三个参数权限集合,否则Spring Security会将其判定为未认证的凭证,后续请求会被拦截要求重新登录
  • 你自定义了Session中安全上下文的属性名为my-security-context,直接使用注入的ServerSecurityContextRepository实例调用save方法会自动匹配你配置的属性名,无需额外处理

内容的提问来源于stack exchange,提问作者user1578872

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:24:00