gpt4 book ai didi

Java Web GoogleSignin - GoogleIdTokenVerifier 验证 token 字符串返回 null

转载 作者:搜寻专家 更新时间:2023-11-01 02:02:13 25 4
gpt4 key购买 nike

我正在将 google 注册/登录添加到我的网络应用程序,但我遇到了问题。

这是我的代码:

private static final HttpTransport transport = new NetHttpTransport();
private static final JsonFactory jsonFactory = new JacksonFactory();
private static final String MY_APP_GOOGLE_CLIENT_ID = "wouldntyouliketoknow";

public UsernamePasswordAuthenticationToken verify(final String idTokenString){

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
.setAudience(Collections.singletonList(MY_APP_GOOGLE_CLIENT_ID))
.build();

try {
GoogleIdToken idToken = verifier.verify(idTokenString);// <-- verifier.verify returns null !!!
if (idToken != null) {
Payload payload = idToken.getPayload();
String email = payload.getEmail();
if(Boolean.valueOf(payload.getEmailVerified())){
UserJPA jpa = userRepository.findByEmail(email);
if(jpa==null){
throw new UsernameNotFoundException("Cannot find user with email = "+email);
}
if(!jpa.isRegisterredWithGoogle()){
throw new UsernameNotFoundException("This user did not use the 'Register with google' option.");
}
bokiAuthenticationProvider.checkUserActiveAndUnlocked(jpa);

return new UsernamePasswordAuthenticationToken(jpa.getUsername(), jpa.getPasswordHesh(),
bokiAuthenticationProvider.getAuthorities(jpa.getUserHasRoleSecurityList()));
}
}else{
System.out.println("The *idToken* object is null !!!");
}
} catch (GeneralSecurityException | IOException e) {
e.printStackTrace();
}

throw new MyCustomException("Google token is invalid or has expired");
}

为了创建我的 CLIENT_ID,我遵循了此处的说明:

https://developers.google.com/identity/sign-in/web/devconsole-project

问题是 verifier.verify 一直返回 null

我检查过:

  • 我的用户确实在 google 上注册并且数据库字段已正确填写

  • 我每次尝试 google_sign_in 时都会从 google 获得不同的字符串标记

  • 我的 CLIENT_ID 在 google 控制台中有效且活跃。

更令人困惑的是,整个事情在一个月前还运行良好。我请病假离开,当我回来时,我的老板就这个问题欢迎我。

有人知道可能发生了什么吗?

最佳答案

我终于明白了。

因为没有人知道如何帮助我,所以我放弃了指定的谷歌库并从头开始制作我自己的 token 验证。

我在这里使用了 google-token-verifier-url-tool :

https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123

这里是页面底部

https://developers.google.com/identity/protocols/OpenIDConnect

,我找到了如何破译 json。

我所做的是,我在代码中联系他们的在线工具,获取 json 响应并手动验证它。这是我的代码:

    private Map<String,String> getMapFromGoogleTokenString(final String idTokenString){
BufferedReader in = null;
try {
// get information from token by contacting the google_token_verify_tool url :
in = new BufferedReader(new InputStreamReader(
((HttpURLConnection) (new URL("https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" + idTokenString.trim()))
.openConnection()).getInputStream(), Charset.forName("UTF-8")));

// read information into a string buffer :
StringBuffer b = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null){
b.append(inputLine + "\n");
}

// transforming json string into Map<String,String> :
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(b.toString(), objectMapper.getTypeFactory().constructMapType(Map.class, String.class, String.class));

// exception handling :
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch(Exception e){
System.out.println("\n\n\tFailed to transform json to string\n");
e.printStackTrace();
} finally{
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}

// chack the "email_verified" and "email" values in token payload
private boolean verifyEmail(final Map<String,String> tokenPayload){
if(tokenPayload.get("email_verified")!=null && tokenPayload.get("email")!=null){
try{
return Boolean.valueOf(tokenPayload.get("email_verified")) && tokenPayload.get("email").contains("@gmail.");
}catch(Exception e){
System.out.println("\n\n\tCheck emailVerified failed - cannot parse "+tokenPayload.get("email_verified")+" to boolean\n");
}
}else{
System.out.println("\n\n\tCheck emailVerified failed - required information missing in the token");
}
return false;
}

// check token expiration is after now :
private boolean checkExpirationTime(final Map<String,String> tokenPayload){
try{
if(tokenPayload.get("exp")!=null){
// the "exp" value is in seconds and Date().getTime is in mili seconds
return Long.parseLong(tokenPayload.get("exp")+"000") > new java.util.Date().getTime();
}else{
System.out.println("\n\n\tCheck expiration failed - required information missing in the token\n");
}
}catch(Exception e){
System.out.println("\n\n\tCheck expiration failed - cannot parse "+tokenPayload.get("exp")+" into long\n");
}
return false;
}

// check that at least one CLIENT_ID matches with token values
private boolean checkAudience(final Map<String,String> tokenPayload){
if(tokenPayload.get("aud")!=null && tokenPayload.get("azp")!=null){
List<String> pom = Arrays.asList("MY_CLIENT_ID_1",
"MY_CLIENT_ID_2",
"MY_CLIENT_ID_3");

if(pom.contains(tokenPayload.get("aud")) || pom.contains(tokenPayload.get("azp"))){
return true;
}else{
System.out.println("\n\n\tCheck audience failed - audiences differ\n");
return false;
}
}
System.out.println("\n\n\tCheck audience failed - required information missing in the token\n");
return false;
}

// verify google token payload :
private boolean doTokenVerification(final Map<String,String> tokenPayload){
if(tokenPayload!=null){
return verifyEmail(tokenPayload) // check that email address is verifies
&& checkExpirationTime(tokenPayload) // check that token is not expired
&& checkAudience(tokenPayload) // check audience
;
}
return false;
}

一旦我进行了详细的验证,我就能准确地看出错误在哪里;前端向我发送了无效的 CLIENT_ID 值。 [提示,提示] 我已经问过他们大约一百次了,他们告诉我这些值(value)观是一致的。 呸!

所以错误不在我原来的 token 验证代码中的某个地方,而是我办公室的通信错误。

为了安全起见,这次我将使用正确的 CLIENT_ID 恢复到原始代码。不过,我必须对谷歌图书馆提出一个提示——它从来没有告诉我为什么 token 验证失败。我花了好几天的时间才终于弄明白。我知道他们这样做是出于安全考虑,但缺乏支持仍然令人痛心。

关于Java Web GoogleSignin - GoogleIdTokenVerifier 验证 token 字符串返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43043526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com