使用spring security以编程方式登录用户

Nim*_*sky 59 spring-mvc spring-security

与之相反:如何使用spring security手动注销用户?

在我的应用程序中,我已经注册了新用户屏幕,该屏幕发布到控制器,该控制器在db中创建新用户(并进行一些明显的检查).然后我希望这个新用户自动登录...我有点想要一些东西像这样 :

SecurityContextHolder.getContext().setPrincipal(MyNewUser);
Run Code Online (Sandbox Code Playgroud)

编辑 好我几乎已经基于如何以Spring Security 3.1以编程方式登录用户的答案实现

 Authentication auth = new UsernamePasswordAuthenticationToken(MyNewUser, null);
 SecurityContextHolder.getContext().setPrincipal(MyNewUser);
Run Code Online (Sandbox Code Playgroud)

但是,在部署时,jsp无法访问我,MyNewUser.getWhateverMethods()而在正常登录过程之后也是如此.这个代码在名义上有效,但在登录时会抛出错误如下:

<sec:authentication property="principal.firstname" /> 
Run Code Online (Sandbox Code Playgroud)

Nim*_*sky 38

在我的控制器中我有这个,它正常登录用户:

Authentication auth = 
  new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());

SecurityContextHolder.getContext().setAuthentication(auth);
Run Code Online (Sandbox Code Playgroud)

用户是我新创建的自定义用户对象(实现UserDetails).该getAuthorities()方法执行此操作(仅因为我的所有用户都具有相同的角色):

public Collection<GrantedAuthority> getAuthorities() {
        //make everyone ROLE_USER
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        GrantedAuthority grantedAuthority = new GrantedAuthority() {
            //anonymous inner type
            public String getAuthority() {
                return "ROLE_USER";
            }
        }; 
        grantedAuthorities.add(grantedAuthority);
        return grantedAuthorities;
    }
Run Code Online (Sandbox Code Playgroud)

  • 您无需在问题的描述方案中进行身份验证.用户刚刚注册.那是"认证".只需要以编程方式将用户添加到上下文中,以便Spring知道用户已经过身份验证. (14认同)
  • 这不是登录,即"将用户对象置于安全上下文中而不对其进行身份验证" (7认同)
  • 我在这里放置了更完整的解决方案:http://stackoverflow.com/a/38868001/999367 (2认同)
  • 将 GrantedAuthority 作为第三个参数添加到 UsernamePasswordAuthenticationToken 是我所需要的 (2认同)

aco*_*hen 28

您还可以将配置的Spring安全性注入UserDetailsManager控制器,并使用它来获取UserDetails保存主体和权限的内容以避免重复代码:

// inject

@Autowired
private UserDetailsManager manager; 

// use in your method

UserDetails userDetails = manager.loadUserByUsername (token.getUsername ());
Authentication auth = new UsernamePasswordAuthenticationToken (userDetails.getUsername (),userDetails.getPassword (),userDetails.getAuthorities ());
SecurityContextHolder.getContext().setAuthentication(auth);
Run Code Online (Sandbox Code Playgroud)


Sim*_*eon 10

从春季安全来源AbstractAuthenticationProcessingFilter:

protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        Authentication authResult) throws IOException, ServletException {

    if (logger.isDebugEnabled()) {
        logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
    }

    // you need this
    SecurityContextHolder.getContext().setAuthentication(authResult);

    rememberMeServices.loginSuccess(request, response, authResult);

    if (this.eventPublisher != null) {
        eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
    }

    successHandler.onAuthenticationSuccess(request, response, authResult);
}
Run Code Online (Sandbox Code Playgroud)

但请注意,SecurityContextHolder通常在完成过滤器链后清除.