【问题标题】:Token Exchange - Android + Google + Keycloak令牌交换 - Android + Google + Keycloak
【发布时间】: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


    【解决方案1】:

    我修复了它,改变了获取令牌的方式:

    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                String accessToken = GoogleAuthUtil.getToken(
                    getApplicationContext(),
                    account.getAccount().name, "oauth2:"
                            + "https://www.googleapis.com/auth/userinfo.profile" +
                            " https://www.googleapis.com/auth/plus.profile.emails.read");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    }.execute();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-23
      • 2019-03-16
      • 2021-02-03
      • 2011-01-19
      • 2018-07-27
      • 2012-09-16
      相关资源
      最近更新 更多