【发布时间】:2012-04-17 12:25:24
【问题描述】:
我使用这样的代码进行身份验证:
@PreAuthorize("isAnonymous()")
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String doLogin(HttpServletRequest request) {
try {
Authentication req = new UsernamePasswordAuthenticationToken(request.getParameter("name"),
request.getParameter("password"));
Authentication result = authenticationManager.authenticate(req);
SecurityContextHolder.getContext().setAuthentication(result);
logger.debug("Success login");
logger.debug(SecurityContextHolder.getContext().getAuthentication());
return "index";
} catch (AuthenticationException e) {
e.printStackTrace();
logger.debug("ACHTUNG! Success failed");
return "index";
}
}
我可以登录,它可以工作。我在日志中看到非空身份验证对象。 然后我尝试浏览一些像这样的安全页面:
@PreAuthorize("hasRole('user')")
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String user(ModelMap modelMap) {
modelMap.addAttribute("user", SecurityContextHolder.getContext().getAuthentication().getCredentials().toString());
return "index";
}
由于 getAuthentication(),它会抛出 NullPointerException。 当我使用 SecurityContextHolder.MODE_INHERITABLETHREADLOCAL 和 SecurityContextHolder.MODE_INHERITABLETHREADLOCAL 时会发生这种情况,这与使用 SecurityContextHolder.MODE_GLOBAL 不同。
我做错了什么?我不需要 SecurityContextHolder 的 MODE_GLOBAL 行为。
UPD:有时会出现问题,有时不会出现在同一个会话中。
【问题讨论】:
-
确保您的
/login页面未配置filters = "none": stackoverflow.com/questions/3923296/… -
您确定 NPE 来自 getAuthentication() 的结果(例如,Authentication 对象为空)?这是在您登录的同一个请求中,还是在您从登录页面重定向之后?
-
@peter 是的,我查过了。由 getAuthentication() 引起的 NPE。不,不同的请求。
-
正如@axtavt 提到的,这几乎总是因为安全过滤器在请求之前没有运行。我会在 NPE 之前设置一个断点或进行堆栈转储,然后查看调用堆栈以查看安全过滤器是否在调用堆栈中。
标签: java spring spring-security security-context