#android #keycloak #passport-google-oauth2 #token-exchange
#Android #поиск ключей #паспорт-google-oauth2 #обмен токенами
Вопрос:
Контекст:
Я разрабатываю собственное приложение для Android, аутентифицирую его с помощью входа в Google, и оно работает.
У меня также есть сервер Keycloak, интегрированный с Google в качестве поставщика удостоверений, и он также работает.
Я могу импортировать свою учетную запись из Google при первом входе в систему, используя доступ к веб-браузеру http://localhost:8080/auth/realms/chapa/account /.
Когда я захожу в консоль Keycloak, я нахожу, что моя учетная запись создана и связана с Google.
Моя настройка поставщика удостоверений Google была выполнена с использованием (OpenID Connect v1 https://accounts.google.com/.well-known/openid-configuration ) или социальный Google на Keycloak.
Оба способа работают с использованием навигации по браузеру, так как я видел, что мало кто жаловался на то, что плагин Keycloak был сломан.
Моя проблема:
В моем приложении для Android я не могу выполнить обмен токенами с сервером Keycloak.
Я провел исследование, и это единственный способ интегрировать Android Google Keycloak, поскольку я не хочу снова запрашивать свои учетные данные пользователя. Пожалуйста, дайте мне знать, если вы знаете другие способы.
На моем сервере Keycloak я получаю что-либо еще, кроме этого ПРЕДУПРЕЖДЕНИЯ:
08:09:48 831 ПРЕДУПРЕЖДЕНИЕ [org.keycloak.events] (задача по умолчанию-11) type=TOKEN_EXCHANGE_ERROR, realmId=my-realm, ClientID=android-app, userId= null, IPAddress = 172.17.0.1, ошибка = invalid_token, причина = ‘сбой вызова информации о пользователе’, auth_method=token_exchange,grant_type=urn:ietf:параметры: oauth: тип предоставления: обмен токенами, subject_issuer=https://accounts.google.com, validation_method=’информация о пользователе’, client_auth_method=секрет клиента
Это запрос, который я выполняю против 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"
}
Код Android:
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
Ответ №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();