此快速入门增加了对OAuth 2.0资源所有者密码授予的支持。 这允许客户端将用户名和密码发送到Identityserver,以请求代表该用户的令牌。
注意仅建议对所谓的“受信任的客户端”使用资源所有者密码授予-在许多情况下,最好使用基于OpenID Connect的用户身份验证流程。 但是,此示例允许以简单的方式将用户引入Identityserver-这就是我们将其包括在内的原因。
讲解
与该示例一起提供的教程可在此处找到使用密码保护API
注意
对于任何先决条件(例如模板),请先查看概述。
OAuth 2.0资源所有者密码授予功能允许客户端将用户名和密码发送到令牌服务,并获得代表该用户的访问令牌。
规范通常建议不要使用不能托管浏览器的旧版应用程序,而不使用资源所有者密码授予。 一般来说,当您要验证用户身份并请求访问令牌时,使用交互式OpenID Connect流之一通常会更好。
不过,这种授权类型使我们可以将用户的概念引入我们的快速入门IdentityServer中,这就是我们展示它的原因。
添加用户
就像在内存中存储资源(即合并范围)和客户端一样,也有一个供用户使用。
注意
检查基于ASP.NET身份的快速入门,以获取有关如何正确存储和管理用户帐户的更多信息。
TestUser
类代表测试用户及其声明。 让我们通过将以下代码添加到配置类中来创建几个用户:
首先,将以下using语句添加到Config.cs
文件:
using IdentityServer4.Test;
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password"
},
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "password"
}
};
}
然后向IdentityServer注册测试用户:
public void ConfigureServices(IServiceCollection services)
{
// 使用内存中的存储,密钥,客户端和作用域配置身份服务器
services.AddIdentityServer()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
}
AddTestUsers
扩展方法在后台执行了一些操作
- 增加了对资源所有者密码授予的支持
- 为通常由登录用户界面使用的用户相关服务提供支持(我们将在下一个快速入门中使用它)
- 增加了对基于测试用户的配置文件服务的支持(您将在下一个快速入门中了解有关此信息的更多信息)
为资源所有者密码授予添加客户端
您可以通过更改AllowedGrantTypes
属性,简单地将对授予类型的支持添加到我们现有的客户端中。 如果您需要您的客户能够使用绝对支持的两种授予类型。
我们正在为资源所有者用例创建一个单独的客户端,将以下内容添加到您的客户端配置中:
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
// other clients omitted...
// resource owner password grant client
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api1" }
}
};
}
使用密码授予请求令牌
将新的控制台客户端添加到您的解决方案。
新客户端看起来与我们为客户端凭据授予所做的非常相似。 现在的主要区别在于,客户端将以某种方式收集用户的密码,并在令牌请求期间将其发送到令牌服务。
IdentityModel可以再次在这里提供帮助:
// request token
var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "ro.client",
ClientSecret = "secret",
UserName = "alice",
Password = "password",
Scope = "api1"
});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
将令牌发送到身份API端点时,与客户端凭据授予相比,您会注意到一个很小但重要的区别。 现在,访问令牌将包含一个唯一声明用户的子声明。 可以通过在调用API之后检查内容变量来查看此“附属”声明,并且该声明也将由控制台应用程序显示在屏幕上。
从属权利要求的存在(或不存在)使API可以区分代表客户端的调用和代表用户的调用。
网友评论