0

我使用这样的代码进行身份验证:

@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:有时会出现问题,有时不会在同一个会话中。

4

1 回答 1

1

Make absolutely sure that the Security Filter is running each time in your request by logging:

request.getAttribute("__spring_security_scpf_applied");

Do not. Do not replace the SecurityContextHolderStrategy unless you absolutely know what your doing. It has to do with finding the SecurityContext based on ThreadLocal. So unless your a very weird Servlet Container the default is almost always correct.

You also need to make an interceptor for your request path. The @PreAuthorize only applies to method calls http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html which is not what you want.

Instead you want something like the following in your security application context:

<http> ...
        <intercept-url pattern="/user**" access="hasRole('user')" />
</http>
于 2012-04-17T15:46:50.183 回答