【发布时间】:2022-01-12 08:20:28
【问题描述】:
上下文:
我正在开发一个原生 Android 应用,通过 Google SignIn 对其进行身份验证,并且它正在运行。
我还有一个 Keycloak 服务器作为身份提供者与 Google 集成,它也可以工作。
我可以在我第一次登录时从 Google 导入我的帐户,使用网络浏览器访问 http://localhost:8080/auth/realms/chapa/account/。
当我转到 Keycloak 控制台时,我发现我的帐户已创建并与 Google 关联。
我的 Google 身份提供程序设置是使用 (OpenId Connect v1 + https://accounts.google.com/.well-known/openid-configuration) 或 Keycloak 上的 Social Google 完成的。
这两种方法都可以使用浏览器导航,因为我看到很少有人抱怨 Keycloak 插件坏了。
我的问题:
在我的 Android 应用上,我无法与 Keycloak 服务器执行令牌交换。
我做了一项研究,这是集成 Android + Google + Keycloak 的唯一方法,因为我不想再次询问我的用户凭据。如果您知道其他方法,请告诉我。
在我的 Keycloak 服务器上,我得到的不是这个警告:
08:09:48,831 WARN [org.keycloak.events](默认任务 11) type=TOKEN_EXCHANGE_ERROR, realmId=my-realm, clientId=android-app, userId=null, ipAddress=172.17.0.1, error=invalid_token, reason='user 信息调用失败', auth_method=token_exchange, grant_type=urn:ietf:params:oauth:grant-type:token-exchange, subject_issuer=https://accounts.google.com, validation_method='user info', client_auth_method=client-secret
这是我对 Keycloak 执行的请求,在 Postman 上手动执行,期望交换令牌:
curl --location --request POST 'http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=android-app' \
--data-urlencode 'client_secret=a1739b19-3131-4f5c-ba31-8d24afff8d84' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:refresh_token' \
--data-urlencode 'subject_token=eyJhbGciOiJSUzI1NiIsImtpZCI6... (truncated)' \
--data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:jwt' \
--data-urlencode 'subject_issuer=google'
邮递员响应(400 错误请求):
{
"error": "invalid_token",
"error_description": "invalid token"
}
安卓代码:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken(clientId) //same client id used on Keycloak Identity Provider
.requestScopes(new Scope(Scopes.PROFILE), new Scope(Scopes.PLUS_ME), new Scope(Scopes.EMAIL))
.build();
GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(getApplicationContext(), gso);
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(getApplicationContext());
Log.w("getServerAuthCode", account.getServerAuthCode()); //null
Log.w("getIdToken", account.getIdToken()); //value passed on Postman subject_token parameter
【问题讨论】:
标签: android keycloak passport-google-oauth2 token-exchange