How to integrate Angular ts Http (with credentials

2019-06-05 18:52发布

问题:

it would be best if there is a document or example that is available to the public to show how to integrate Angular http(with credentials) with Spring Security.

I have a way to login which I will show the code below, but I think there must be a better way. Maybe with the option in the Http header withCredentials, but where you provide your credentials?

It is keeping idToken from external auth. service (Google+) and type ( determine type of the auth. service) in headers, so you dont need pass them as a request parameter or as a path variable.

Then in the backend (Spring Java), there is a spring AOP that save the user to the SecurityContext after verification.

Angular Http Call

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)
        ...

GooglePlusAuthService

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;
    }
}

This code has a bug which I am also trying to find out.

Why AuthenticationUtils.getUser() is giving me the last signed in user when I didn't provide any credential info. I just opened the url with a private browser and it gets me the last signed in user in the backend.