keycloak - 如何通过 API 集成 keycloak 短信认证?
问题描述
我有一个使用自定义 KeycloakProvider 的 keycloak 服务器和 Laravel 应用程序:
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);
}
现在我的目标是通过用户的手机号码设置基本的短信认证。我找到了一些工具(1、2),但它们不提供 API,只提供 HTML 页面。有解决办法吗?
解决方案
我找到了解决方案。在不知道某人密码的情况下登录:
- 发简讯;
- 通过代码确认电话号码;
- 获取目标用户的keycloak ID;
- 以具有冒充权限的用户身份登录;
- 与目标用户交换代币。
TOKEN_EXCHANGE
需要keycloak功能。
步骤 1-3 我使用 Laravel 实现,步骤 4-5 使用 Keycloak API:
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);
}
推荐阅读
- javascript - 用于在本地列出和显示图像的 HTML 页面
- angular - 如何将样式包含到 Angular 单元测试中
- python - 对 pandas 数据框的每一列进行多次探索性测试
- google-maps - 如何在 Xamarin Forms 中设置自动日/夜模式谷歌地图
- sql - 根据另一个表中的列名从一个表中选择列
- r - 如何 gganimate 堆积条形图?
- linux - Telegraf 输入插件:如何确定从哪个服务接受输入
- git - 如何在 git 中列出所有错误合并到发布分支的提交?
- html - 如何使 flexbox 'justify-content: space-between' 生效?
- sas - Teradata QUERY_BAND 的 SAS/ACCESS 接口