对于经过身份验证的用户,我有一个公开的端点可以更新安全上下文,该方法具有此代码
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
,也没有帮助
“此 API 与其他 API 一起调用,但未更新上下文”是什么意思?
如果您的意思是: 调用 API updateUser(在 Spring Security 中创建身份验证),然后调用需要身份验证的其他 API -> 这将不起作用。
原因如下: 请求中的每个 Spring 上下文持有者都是不同的。因此,您不能调用一个 API 来允许,然后调用另一个 API 来请求资源。您需要在一次 API 调用中允许并请求资源。例如,当您调用 API 来请求资源时,您需要在标头中提供访问令牌。然后,在服务器上,您使用过滤器检查访问令牌是否有效,在 Spring Security 上下文中设置身份验证,处理资源请求并返回响应。