- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在将 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/
我正在开发一个应用程序,它使用 OAuth - 基于 token 的身份验证。 考虑到我们拥有访问和刷新 token ,这就是流程的样子。 Api call -> intercepter append
如何取消标记此代码的输出? 类(class)核心: def __init__(self, user_input): pos = pop(user_input) subject = ""
当我使用命令 kubectl 时与 --token标记并指定 token ,它仍然使用 kubeconfig 中的管理员凭据文件。 这是我做的: NAMESPACE="default" SERVICE
我正在制作 SPA,并决定使用 JWT 进行身份验证/授权,并且我已经阅读了一些关于 Tokens 与 Cookies 的博客。我了解 cookie 授权的工作原理,并了解基本 token 授权的工作
我正在尝试从应用服务获取 Google 的刷新 token ,但无法。 日志说 2016-11-04T00:04:25 PID[500] Verbose Received request: GET h
我正在开发一个项目,只是为了为 java 开发人员测试 eclipse IDE。我是java新手,所以我想知道为什么它不起作用,因为我已经知道该怎么做了。这是代码: public class ecli
我正在尝试使用 JwtSecurityTokenHandler 将 token 字符串转换为 jwt token 。但它出现错误说 IDX12709: CanReadToken() returned
我已阅读文档 Authentication (来自 Facebook 的官方)。我仍然不明白 Facebook 提供的这三种访问 token 之间的区别。网站上给出了一些例子,但我还是不太明白。 每个
我的部署服务器有时有这个问题,这让我抓狂,因为我无法在本地主机中重现,我已经尝试在我的 web.config 中添加机器 key ,但没有成功远。 它只发生在登录页面。 我的布局:
我已经设法获得了一个简单的示例代码,它可以创建一个不记名 token ,还可以通过阅读 stackoverflow 上的其他论坛来通过刷新 token 请求新的不记名 token 。 启动类是这样的
如果我有以前的刷新 token 和使用纯 php 的访问 token ,没有 Google Api 库,是否可以刷新 Google Api token ?我在数据库中存储了许多用户刷新和访问 toke
我通过 Java 应用程序使用 Google 电子表格时遇到了问题。我创建了应用程序,该应用程序运行了 1 年多,没有任何问题,我什至在 Create Spreadsheet using Google
当我有一个有效的刷新 token 时,我正在尝试使用 Keycloak admin REST API 重新创建访问 token 。 我已经通过调用 POST/auth/realms/{realm}/p
我正在尝试让第三方 Java 客户端与我编写的 WCF 服务进行通信。 收到消息时出现如下异常: Cannot find a token authenticator for the 'System.I
在尝试将数据插入到我的 SQl 数据库时,我收到以下错误 System.Data.SqlServerCe.SqlCeException: There was an error parsing the
使用数据库 session token 系统,我可以让用户使用用户名/密码登录,服务器可以生成 token (例如 uuid)并将其存储在数据库中并将该 token 返回给客户端。其上的每个请求都将包
我最近注册了 Microsoft Azure 并设置了认知服务帐户。使用 Text Translation API Documentation 中的说明我能够使用 interactive online
我使用 IAntiforgery API 创建了一个 ASP.Net Core 2 应用程序。 这提供了一种返回 cookie 的方法。 客户端获取该 cookie,并在后续 POST 请求中将该值放
我正在使用 spacy 来匹配某些文本(意大利语)中的特定表达式。我的文本可以多种形式出现,我正在尝试学习编写一般规则的最佳方式。我有如下 4 个案例,我想写一个适用于所有案例的通用模式。像这样的东西
我无法理解 oauth 2.0 token 的原则处理。 我的场景是,我有一个基于 web 的前端后端系统,带有 node.js 和 angular 2。用户应该能够在此站点上上传视频。然后创建一些额
我是一名优秀的程序员,十分优秀!