首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Spring Security / SpringMVC中手动设置认证用户

如何在Spring Security / SpringMVC中手动设置认证用户
EN

Stack Overflow用户
提问于 2011-01-12 10:44:12
回答 6查看 189.2K关注 0票数 114

在新用户提交“新帐户”表单后,我希望手动登录该用户,这样他们就不必在后续页面上登录。

通过spring安全拦截器的普通表单登录页面工作得很好。

在新的帐户表单控制器中,我创建了一个UsernamePasswordAuthenticationToken,并在SecurityContext中手动设置它:

代码语言:javascript
复制
SecurityContextHolder.getContext().setAuthentication(authentication);

在同一页面上,我稍后检查用户是否使用以下命令登录:

代码语言:javascript
复制
SecurityContextHolder.getContext().getAuthentication().getAuthorities();

这将返回我之前在身份验证中设置的权限。平安无事。

但是,当在我加载的下一个页面上调用相同的代码时,身份验证令牌只是UserAnonymous。

我不清楚为什么它没有保留我在前一个请求上设置的身份验证。有什么想法吗?

  • 是否与会话ID设置不正确有关?
  • 是否可能覆盖了我的身份验证somehow?
  • Perhaps我只需要另一个步骤来保存authentication?
  • Or是否需要执行某些操作才能声明整个会话的身份验证,而不是单个请求?

只是在寻找一些想法,可能会帮助我了解这里发生了什么。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-01-13 01:48:08

前段时间我遇到了和你一样的问题。我不记得细节了,但是下面的代码为我做了一些事情。此代码在Spring Webflow流中使用,因此出现了RequestContext和ExternalContext类。但与您最相关的部分是doAutoLogin方法。

代码语言:javascript
复制
public String registerUser(UserRegistrationFormBean userRegistrationFormBean,
                           RequestContext requestContext,
                           ExternalContext externalContext) {

    try {
        Locale userLocale = requestContext.getExternalContext().getLocale();
        this.userService.createNewUser(userRegistrationFormBean, userLocale, Constants.SYSTEM_USER_ID);
        String emailAddress = userRegistrationFormBean.getChooseEmailAddressFormBean().getEmailAddress();
        String password = userRegistrationFormBean.getChoosePasswordFormBean().getPassword();
        doAutoLogin(emailAddress, password, (HttpServletRequest) externalContext.getNativeRequest());
        return "success";

    } catch (EmailAddressNotUniqueException e) {
        MessageResolver messageResolvable 
                = new MessageBuilder().error()
                                      .source(UserRegistrationFormBean.PROPERTYNAME_EMAIL_ADDRESS)
                                      .code("userRegistration.emailAddress.not.unique")
                                      .build();
        requestContext.getMessageContext().addMessage(messageResolvable);
        return "error";
    }

}


private void doAutoLogin(String username, String password, HttpServletRequest request) {

    try {
        // Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
        token.setDetails(new WebAuthenticationDetails(request));
        Authentication authentication = this.authenticationProvider.authenticate(token);
        logger.debug("Logging in with [{}]", authentication.getPrincipal());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    } catch (Exception e) {
        SecurityContextHolder.getContext().setAuthentication(null);
        logger.error("Failure in autoLogin", e);
    }

}
票数 63
EN

Stack Overflow用户

发布于 2011-12-01 11:34:57

我找不到任何其他完整的解决方案,所以我想我会发布我的。这可能有点小问题,但它解决了上面的问题:

代码语言:javascript
复制
public void login(HttpServletRequest request, String userName, String password)
{

    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(userName, password);

    // Authenticate the user
    Authentication authentication = authenticationManager.authenticate(authRequest);
    SecurityContext securityContext = SecurityContextHolder.getContext();
    securityContext.setAuthentication(authentication);

    // Create a new session and add the security context.
    HttpSession session = request.getSession(true);
    session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
}
票数 69
EN

Stack Overflow用户

发布于 2011-01-13 09:57:47

最终找到了问题的根源。

当我手动创建安全上下文时,没有创建任何会话对象。只有当请求完成处理时,Spring Security机制才会意识到session对象是空的(当它试图在处理请求之后将安全上下文存储到会话中时)。

在请求的末尾,Spring Security创建一个新的session对象和session ID,但是这个新的session ID永远不会到达浏览器,因为它出现在请求的末尾,在对浏览器做出响应之后。当下一个请求包含以前的会话ID时,这会导致新的会话ID (以及包含我手动登录的用户的安全上下文)丢失。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4664893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档