Java 如何将Http(带凭据)与Spring安全性集成

Java 如何将Http(带凭据)与Spring安全性集成,java,angular,spring-security,angular-http,Java,Angular,Spring Security,Angular Http,最好是有一个文档或示例可供公众使用,以展示如何将Angular http(带凭据)与Spring安全性集成 我有一个登录的方法,我将显示下面的代码,但我认为一定有更好的方法。可能在Http头中使用该选项,但您在哪里提供凭据 它正在阻止idToken进行外部身份验证。服务(Google+)和类型(确定auth.service的类型)在标题中,所以您不需要将它们作为请求参数或路径变量传递 然后在后端(SpringJava),有一个SpringAOP,在验证后将用户保存到SecurityContext

最好是有一个文档或示例可供公众使用,以展示如何将Angular http(带凭据)与Spring安全性集成

我有一个登录的方法,我将显示下面的代码,但我认为一定有更好的方法。可能在Http头中使用该选项,但您在哪里提供凭据

它正在阻止idToken进行外部身份验证。服务(Google+)和类型(确定auth.service的类型)在标题中,所以您不需要将它们作为请求参数或路径变量传递

然后在后端(SpringJava),有一个SpringAOP,在验证后将用户保存到SecurityContext

角度Http调用

import { Http, Headers, RequestOptions } from '@angular/http';
...
constructor(private http: Http...){...}
...
search(){
    let options ;
    if (this.loginService.user) {
        let headers = new Headers({ 'idToken': this.loginService.user.idToken,'type':this.loginService.user.type});
        options = new RequestOptions({ headers: headers });
    }
    return this.http
        .get("searchurl",options)
        ...
谷歌plusauthservice

import java.util.Collections;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;

@Service
public class GooglePlusAuthService implements AuthenticationService{

    private Logger logger = LoggerFactory.getLogger(GooglePlusAuthService.class);
    private static String clientId;
    @Value("${client_id.google}")
    public void setClientId(String clientId){
        GooglePlusAuthService.clientId=clientId;
    }
    @Override
    public void login(String token) {
        GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new JacksonFactory())//.setIssuer(clientId)
                .setAudience(Collections.singletonList(clientId))
                .build();

            GoogleIdToken idToken;
            try {
                idToken = verifier.verify(token);
                if (idToken != null) {
                      Payload payload = idToken.getPayload();
                      User user = new User();
                      user.setId(Authenticator.AUTH_TYPE_GOOGLE+"_"+payload.getSubject());
                      user.setUsername((String) payload.get("name"));
                      user.setToken(token);
                      AuthenticationUtils.setUser(user);
                    } else {
                        logger.info("Failed to login with Google plus. Invalid ID token.");
                    }
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Failed to login with Google plus." + e.getMessage());
            }
    }
}
AuthenticationUtils

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class AuthenticationUtils {

    public static void setUser(User user){
        Authentication authentication = new UsernamePasswordAuthenticationToken(user, null);
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }

    public static User getUser(){
        if(SecurityContextHolder.getContext().getAuthentication()!=null)
            return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return null;
    }
}
这段代码有一个bug,我也在试图找出它


为什么
AuthenticationUtils.getUser()
在我没有提供任何凭据信息的情况下给我最后一个登录的用户。我刚刚用专用浏览器打开了url,它为我获取了后端的最后一个登录用户。

将用户凭据嵌入http头中有什么问题?@MikeTung它工作得很好,但出于某种原因,SecurityContext总是返回最后一个保存用户,即使没有凭证被传递,您是否确保您的缓存头被禁用,并且spring security始终清空以前用户的数据?@MikeTung没有凭证信息传递到头中,不知何故旧上下文仍然存在。我们不需要自己清理
SecurityContext
,因为它在请求范围或会话范围内。因为当我有浏览器和手机时,我们肯定会有一个新的
SecurityContext
。事实上,当您启动私有浏览器(Firefox术语)时,它将有一个新的
SecurityContext
。在http头中嵌入用户凭据有什么问题?@MikeTung它工作得很好,但出于某种原因,SecurityContext总是返回最后一个保存的用户,即使没有凭证被传递,您是否确保您的缓存头被禁用,并且spring security始终清空以前用户的数据?@MikeTung没有凭证信息传递到头中,不知何故旧上下文仍然存在。我们不需要自己清理
SecurityContext
,因为它在请求范围或会话范围内。因为当我有浏览器和手机时,我们肯定会有一个新的
SecurityContext
。事实上,当您启动私有浏览器(Firefox术语)时,它将有一个新的
SecurityContext