Spring Security 上下文未正确更新

问题描述 投票:0回答:1

对于经过身份验证的用户,我有一个公开的端点可以更新安全上下文,该方法具有此代码

public void setGlobalFilterConfig(GlobalFilterDto globalFilterDto) {
        SecurityContext context = SecurityContextHolder.getContext();
        LocalUser localUser = (LocalUser) context.getAuthentication().getPrincipal();
        Collection<GrantedAuthority> authorities = localUser.getAuthorities();
                localUser.getUser().setGlobalFilterDto(globalFilterDto);
            LoginUserUtils.updateUser(localUser.getUser(), authorities);
    }

本地用户类:

public class LocalUser extends org.springframework.security.core.userdetails.User {
  private UserSessionDto user;

}

LoginUserUtils 类:

@UtilityClass
public class LoginUserUtils {
    public static void updateUser(UserSessionDto user, Collection<GrantedAuthority> authorities) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        LocalUser localUser = (LocalUser) principal;
        localUser.setUser(user);
        Authentication newAuth = new UsernamePasswordAuthenticationToken(localUser,
                auth.getCredentials(),
                authorities);
        SecurityContextHolder.getContext().setAuthentication(newAuth);
    }
}

这里的问题是,当这个 api 单独调用时,它会按预期更新,但是当这个 API 与其他 API 一起调用时,它不会更新 Context

我使用 Spring Security 6.2.3 和 Redis 作为会话存储,当我使用 Spring security 5.x.x 时,这同样可以工作

当我使用注销用户时也会看到同样的行为

    private static final SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();

    private void invalidateSession(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        logoutHandler.logout(request, response, authentication);
    }

我尝试使用手动保存上下文

org.springframework.security.web.context.SecurityContextRepository.saveContext(req,res,auth)
也有同样的问题

即使我尝试将

FLUSH_MODE
中的
IMMEDIATE
@EnableRedisIndexedHttpSession
更改为
ON_SAVE
,也没有帮助

java spring spring-boot spring-security spring-session
1个回答
0
投票

“此 API 与其他 API 一起调用,但未更新上下文”是什么意思?

如果您的意思是: 调用 API updateUser(在 Spring Security 中创建身份验证),然后调用需要身份验证的其他 API -> 这将不起作用。

原因如下: 请求中的每个 Spring 上下文持有者都是不同的。因此,您不能调用一个 API 来允许,然后调用另一个 API 来请求资源。您需要在一次 API 调用中允许并请求资源。例如,当您调用 API 来请求资源时,您需要在标头中提供访问令牌。然后,在服务器上,您使用过滤器检查访问令牌是否有效,在 Spring Security 上下文中设置身份验证,处理资源请求并返回响应。

© www.soinside.com 2019 - 2024. All rights reserved.