如何通过API集成keycloak短信认证?
How to integrate keycloak sms authentication by API?
我有一个 keycloak 服务器和 Laravel 使用自定义 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);
}
现在我的目标是通过用户的手机 phone 号码设置基本的 SMS 身份验证。我找到了一些工具(1, 2),但它们不提供 API,只提供 HTML 页。
有解决办法吗?
我找到了解决办法。
在不知道别人密码的情况下登录:
- 发送短信;
- 通过代码确认phone号码;
- 获取目标用户的keycloak ID;
- 以有权 impersonate;
的用户身份登录
- 与目标用户交换代币。
TOKEN_EXCHANGE
需要 keycloak 功能。
我使用 Laravel 实现的步骤 1-3,使用 Keycloak API 实现的步骤 4-5:
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);
}
我有一个 keycloak 服务器和 Laravel 使用自定义 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);
}
现在我的目标是通过用户的手机 phone 号码设置基本的 SMS 身份验证。我找到了一些工具(1, 2),但它们不提供 API,只提供 HTML 页。 有解决办法吗?
我找到了解决办法。 在不知道别人密码的情况下登录:
- 发送短信;
- 通过代码确认phone号码;
- 获取目标用户的keycloak ID;
- 以有权 impersonate; 的用户身份登录
- 与目标用户交换代币。
TOKEN_EXCHANGE
需要 keycloak 功能。
我使用 Laravel 实现的步骤 1-3,使用 Keycloak API 实现的步骤 4-5:
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);
}