我有身份服务器4(skurba)我想使用QrCode(如whatsapp应用程序)登录用户。换句话说,用户登录网络应用程序并希望通过手机扫描二维码以使用移动应用程序登录。我想要 OIDC 和身份服务器 4 中的标准场景。有人建议设备流程,但在设备流程中用户必须输入用户名和密码等凭据。
我创建 API 将设备代码保存在 DeviceCodes 表(身份服务器 4 和 skurba 中的默认表)中,并将其(设备代码)发送到令牌端点。我收到无效的拨款回复。之后,我将此请求发送到设备授权端点:
curl --location 'http://localhost:44310/connect/deviceauthorization' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
--data-urlencode 'client_id=Mahdi' \
--data-urlencode 'scope=openid'
回复是:
{
"device_code": "A3B6F0F20089F3135368E91083588C2750C3396E4D529ACCBFBD9D8DA4EE806D",
"user_code": "337168620",
"verification_uri": "http://localhost:44310/device",
"verification_uri_complete": "http://localhost:44310/device?userCode=337168620",
"expires_in": 300,
"interval": 5
}
所以我将设备代码发送到令牌端点:
curl --location 'http://localhost:44310/connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
--data-urlencode 'client_id=Mahdi' \
--data-urlencode 'device_code=A3B6F0F20089F3135368E91083588C2750C3396E4D529ACCBFBD9D8DA4EE806D'
我得到了这样的回复:
{
"error": "authorization_pending"
}
另一个问题是我想获取特定用户的令牌,在这种情况下用户不特定。
您收到以下错误,因为它缺少设备授权部分。
{ “错误”:“授权_待处理” }
基本上,您想跳过设备授权,要实现这一点,您有 2 个选择:
您可以更改 IdentityServer4 的本机行为,在设备流 (GrantTypes.DeviceCode) 中,您可以通过将其设置为 false 来禁用 RequireUserConsent。我强烈不建议继续使用此选项,因为此方法存在一些漏洞风险。
您可以为设备授权创建新的自定义 API,在其中创建新用户或将现有用户链接到设备,这将允许您在 /connect/token 上使用设备代码并获取访问令牌和刷新令牌(如果您的客户端设置了offline_access)。按照下面的一个例子:
[AllowAnonymous]
[HttpPost("device/authorization")]
public async Task<IActionResult> DeviceAuthorizationAsync(CancellationToken cancellationToken)
{
//Here you can create a new user or use an existing one like I'm doing below
var identityServerUser = new IdentityServerUser("25389eb0-b27a-4d96-bbf8-faaaa98356e8")// Existing UserId
{
IdentityProvider = "local",
AuthenticationTime = DateTime.UtcNow
};
var deviceCode = new DeviceCode
{
ClientId = "my-client-id",
IsAuthorized = true,
Subject = identityServerUser.CreatePrincipal(),
IsOpenId = true,
Lifetime = 300,
CreationTime = DateTime.UtcNow,
AuthorizedScopes = new List<string> { "openid", "offline_access" }
};
var handle = await _deviceFlowCodeService.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);
return Ok(handle); //Returning the DeviceCode to be used inside /connect/token
}
然后您可以使用 /connect/token 中响应中的设备代码
curl --location 'http://localhost:5127/connect/token'
--header '授权:基本 > a5wbF5dGlc2RdmljZTp7OTQ0Q3NztMkE11BRTk3LTQyNjYtQUM0RTFFQTkxjczfQ=='
--header '内容类型:application/x-www-form-urlencoded'
--data-urlencode > 'device_code=E9FADB639D07081DBDC08F991B13971D06A79D289AAC1CBE54BFB20FB60F458F'
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code'