我有一个调用 Servlet 的 java:
public class UserServlet extends HttpServlet {
@Autowired
private UserService userService;
@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
userService.checkUser();
userService.doSomethingRestricted();
}
@Override
public void init(final ServletConfig config) throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
super.init(config);
}
}
还有我的自动接线服务:
@Component(value = "userService")
public class UserService {
public boolean checkUser() {
if (SecurityContextHolder.getContext().getAuthentication() != null) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getPrincipal() != null && auth.getPrincipal() instanceof User) {
User springUser = (User) auth.getPrincipal();
if (springUser != null) {
LOG.debug("USER CONNECTED :: {}", springUser.getUsername());
}
}
} else {
LOG.debug("NO CONNECTED USER, CREATING ONE");
Collection<GrantedAuthority> authorities = getGrantedAuthorities();
org.springframework.security.core.userdetails.User springUser = new org.springframework.security.core.userdetails.User("user","password", true, true, true, true, authorities);
Authentication auth = new UsernamePasswordAuthenticationToken(springUser, "", authorities);
SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(auth);
SecurityContextHolder.setContext(sc);
}
return true;
}
@Secured({ "CONNECTED" })
public void doSomethingRestricted() {
LOG.debug("SOMETHING RESTRICTED HAS BEEN DONE!!");
}
}
当我第一次测试我的应用程序时,Java 客户端向
POST
服务器发送一个,服务器会检查用户并且找不到上下文:将创建一个新的上下文。当我随后运行 java 客户端时,我找到了一个现有的上下文(在第一次调用中创建的那个)。
显然缺少一些东西,因为如果第一个用户成功登录,并不意味着任何用户都可以连接。
我错过了什么?起初我考虑为每个 Java 客户端的实例使用会话(我没有 Web 浏览器客户端,所以我需要手动设置会话 ID),但是 Spring 什么时候应该在 http 请求中获取或设置会话 ID?
TL;DR :SecurityContextHolder.getContext().getAuthentication()
在我的例子中做了什么?