Java 如何使用Spring安全性以编程方式登录用户?

Java 如何使用Spring安全性以编程方式登录用户?,java,spring-security,Java,Spring Security,我需要以编程方式登录通过Facebook API验证的用户。原因是每个用户都有很多相关的项目(例如购物车),因此,一旦用户使用Facebook API进行身份验证,我需要使用spring security登录该用户,以便能够访问他/她的购物车 根据我的研究,有许多方法可以实现它,但我无法部署其中任何一种,因为我正在从代码发送登录请求,另一个问题是,有些人创建了用户对象,但他们没有解释如何创建它 那些创建用户对象但没有解释如何创建的人 第一个例子: 第二个例子: 第三个例子: 另一方面,它没有帮助

我需要以编程方式登录通过Facebook API验证的用户。原因是每个用户都有很多相关的项目(例如购物车),因此,一旦用户使用Facebook API进行身份验证,我需要使用spring security登录该用户,以便能够访问他/她的购物车

根据我的研究,有许多方法可以实现它,但我无法部署其中任何一种,因为我正在从代码发送登录请求,另一个问题是,有些人创建了用户对象,但他们没有解释如何创建它

那些创建用户对象但没有解释如何创建的人

第一个例子:

第二个例子:

第三个例子:

另一方面,它没有帮助,因为我需要从我自己的代码而不是从浏览器登录用户;因此,我不知道如何填充HttpServletRequest对象

protected void automatedLogin(String username, String password, HttpServletRequest request) {
麦可德

...
if(isAuthenticatedByFB())
{
    login(username);
    return "success";
}
else{
    return "failed";
}
此代码来自,它是在Apache2.0许可证下发布的。我添加了导入只是为了指出具体的类型。原作者是伯特·贝克维思

import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

...

public static void reauthenticate(final String username, final String password) {
    UserDetailsService userDetailsService = getBean("userDetailsService");
    UserCache userCache = getBean("userCache");

    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(
            userDetails, password == null ? userDetails.getPassword() : password, userDetails.getAuthorities()));
    userCache.removeUserFromCache(username);
}

getBean方法仅从应用程序上下文提供bean

不幸的是,Spring security中似乎没有对编程登录的“完全”支持。以下是我如何成功地做到这一点:

@Autowired AuthenticationSuccessHandler successHandler;
@Autowired AuthenticationManager authenticationManager;  
@Autowired AuthenticationFailureHandler failureHandler;

public void login(HttpServletRequest request, HttpServletResponse response, String username, String password) {
    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
    token.setDetails(new WebAuthenticationDetails(request));//if request is needed during authentication
    Authentication auth;
    try {
        auth = authenticationManager.authenticate(token);
    } catch (AuthenticationException e) {
        //if failureHandler exists  
        try {
            failureHandler.onAuthenticationFailure(request, response, e);
        } catch (IOException | ServletException se) {
            //ignore
        }
        throw e;
    }
    SecurityContext securityContext = SecurityContextHolder.getContext();
    securityContext.setAuthentication(auth);
    successHandler.onAuthenticationSuccess(request, response, auth);//if successHandler exists  
    //if user has a http session you need to save context in session for subsequent requests
    HttpSession session = request.getSession(true);
    session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
}

更新Spring的
rememberauthenticationfilter.doFilter()

基本上也是这样做的,谢谢,请您进一步说明。我需要任何requestHandler吗?如何配置该项目?我使用典型的spring安全配置,通常用于处理HTTP请求。当我需要对用户进行内部身份验证时,上面的代码在特殊情况下有效。如何使用oauth 2.0进行身份验证?请说明,您在哪里/如何定义提供给session.setAttribute(…)?@JayEdwards的securityContext变量谢谢您的提问,我修复了代码片段,因此这实际上验证了所有密码是否为真,甚至是坏密码。
...
if(isAuthenticatedByFB())
{
    login(username);
    return "success";
}
else{
    return "failed";
}
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

...

public static void reauthenticate(final String username, final String password) {
    UserDetailsService userDetailsService = getBean("userDetailsService");
    UserCache userCache = getBean("userCache");

    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(
            userDetails, password == null ? userDetails.getPassword() : password, userDetails.getAuthorities()));
    userCache.removeUserFromCache(username);
}
@Autowired AuthenticationSuccessHandler successHandler;
@Autowired AuthenticationManager authenticationManager;  
@Autowired AuthenticationFailureHandler failureHandler;

public void login(HttpServletRequest request, HttpServletResponse response, String username, String password) {
    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
    token.setDetails(new WebAuthenticationDetails(request));//if request is needed during authentication
    Authentication auth;
    try {
        auth = authenticationManager.authenticate(token);
    } catch (AuthenticationException e) {
        //if failureHandler exists  
        try {
            failureHandler.onAuthenticationFailure(request, response, e);
        } catch (IOException | ServletException se) {
            //ignore
        }
        throw e;
    }
    SecurityContext securityContext = SecurityContextHolder.getContext();
    securityContext.setAuthentication(auth);
    successHandler.onAuthenticationSuccess(request, response, auth);//if successHandler exists  
    //if user has a http session you need to save context in session for subsequent requests
    HttpSession session = request.getSession(true);
    session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
}