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