我已通过使用HandlerInterceptor和SoapHandler拦截传入的休息/肥皂请求,在休息/肥皂服务调用中手动添加了Spring身份验证。我将登录的用户名从客户端添加到Web服务,方法是将其添加到soap / rest标头中。我拦截了传入请求并设置了手动身份验证。当我发现认证已经存在时,我将跳过设置。我假设对于每个新的休息/肥皂请求,Web服务(服务器端)都不会进行身份验证。它给我的用户名不是当前用户的新请求。
public UserDetails getUser() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails user= null;
if (auth != null && !(auth instanceof AnonymousAuthenticationToken)) {
// userDetails = auth.getPrincipal()
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = null;
if (principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
user= (UserDetails ) principal;
} else {
username = principal.toString();
}
}
return user;
}
public void setUser(String username) {
// creating spring security context manually
try {
// Must be called from request filtered by Spring Security,
// otherwise SecurityContextHolder is not updated
List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<SimpleGrantedAuthority>();
Authentication authentication;
authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails user;
String uname;
if (principal instanceof UserDetails) {
user= (User) principal;
uname = user.getUsername();
} else {
uname = principal.toString();
}
LOGGER.info("Found username in Spring context: " + uname);
} else {
LOGGER.info("Spring context not found: ");
LOGGER.info("Setting manual authentication.. Username: " + username);
// grantedAuthorities.add(new SimpleGrantedAuthority("USER"));
UserDetails contextUser = new User(username, username, true, true, true, true,
grantedAuthorities, null);
authentication = new UsernamePasswordAuthenticationToken(contextUser, username, grantedAuthorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
SecurityContextHolder.getContext().setAuthentication(null);
LOGGER.error("Failure in creating spring security context authentication", e);
}
}
答案 0 :(得分:1)
这是因为SecurityContext
存储在ThreadLocal
中,并且在Web服务线程完成对请求的处理之后,您从未从ThreadLocal
中清除它,这意味着是否有相同的线程用于处理下一个请求,它仍然保留上一个请求的SecurityContext
。准确地说,在您的情况下,它始终保留第一个使用该线程的用户。
快速的解决方法是您必须在完成每个请求后清除SecurityContext
:
SecurityContextHolder.clearContext();