问题
I have a keycloak server and Laravel application using custom KeycloakProvider:
public function loginByEmail(string $email, string $password): SsoTokens
{
try {
$data = $this->realmEndpoint->makeRequest(
HttpClientProvider::METHOD_POST,
self::KEYCLOAK_AUTH_URL,
[
'client_id' => config('services.keycloak.realm_client'),
'client_secret' => config('services.keycloak.realm_secret'),
'grant_type' => 'password',
'username' => $email,
'password' => $password,
'scope' => 'openid'
]
);
} catch (TransportUnauthorizedException $e) {
throw new UnauthorizedException($e);
} catch (HttpClientException $e) {
throw new TransportException($e);
}
return $this->extractTokens($data);
}
Now my goal is to set up basic SMS authentication by the user's mobile phone number. I found some tools (1, 2), but they don't provide API, just HTML pages. Is there a solution?
回答1:
I found a solution. To login without knowing someone's password:
- Send SMS;
- Confirm phone number by a code;
- Get the keycloak ID of a target user;
- Log in as a user having the right to impersonate;
- Exchange tokens with a target user.
TOKEN_EXCHANGE
keycloak feature required.
Steps 1-3 I implemented with Laravel, steps 4-5 with Keycloak APIs:
public function loginByUserId(string $userId): SsoTokens
{
try {
$impersonatorData = $this->realmEndpoint->makeRequest(
HttpClientProvider::METHOD_POST,
self::KEYCLOAK_AUTH_URL,
[
'client_id' => config('services.keycloak.realm_client'),
'client_secret' => config('services.keycloak.realm_secret'),
'grant_type' => 'password',
'username' => config('services.keycloak.admin_username'),
'password' => config('services.keycloak.admin_password'),
'scope' => 'openid',
]
);
$data = $this->realmEndpoint->makeRequest(
HttpClientProvider::METHOD_POST,
self::KEYCLOAK_AUTH_URL,
[
'client_id' => config('services.keycloak.realm_client'),
'client_secret' => config('services.keycloak.realm_secret'),
'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange',
'requested_subject' => $userId,
'subject_token' => $impersonatorData['access_token'],
'scope' => 'openid',
]
);
} catch (TransportUnauthorizedException $e) {
throw new UnauthorizedException($e);
} catch (HttpClientException $e) {
throw new TransportException($e);
}
return $this->extractTokens($data);
}
来源:https://stackoverflow.com/questions/64385471/how-to-integrate-keycloak-sms-authentication-by-api