一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情
1 配置服务
IdentityServer是中间件和服务的组合,所有配置都在Startup类中配置,首先我们需要注入IdentityServer服务到容器:
public void ConfigureServices(IServiceCollection services)
{
var builder = services.AddIdentityServer();
}
返回一个构建器对象,构建器对象有许多方便的方法来连接其他服务。
2.密钥基本介绍
-
AddSigningCredential
添加签名密钥服务,该服务为各种令牌创建/验证服务提供指定的密钥材料。您可以从证书存储中传入证书的X509Certificate2,SigningCredential或引用。 -
AddDeveloperSigningCredential
在启动时创建临时密钥材料。当您没有要使用的证书时,这仅适用于dev。生成的密钥将保留到文件系统,以便在服务器重新启动之间保持稳定(可以通过传递禁用false)。这解决了客户端/api元数据缓存在开发期间不同步时的问题。 -
AddValidationKey
添加用于验证令牌的密钥。它们将由内部令牌验证器使用,并将显示在发现文档中。您可以从证书存储中传入证书的 X509Certificate2,SigningCredential`或引用。这对于关键翻转场景非常有用。
3.配置存储
“内存中”配置API允许从内存中的配置对象列表配置IdentityServer。这些“内存中”集合可以在宿主应用程序中进行硬编码,也可以从配置文件或数据库动态加载。但是,通过设计,这些集合仅在托管应用程序启动时创建。
-
AddInMemoryClients
基于配置对象的内存中集合的注册IClientStore和ICorsPolicyService实现Client。 -
AddInMemoryIdentityResources
IResourceStore根据IdentityResource配置对象的内存中集合注册实现。 -
AddInMemoryApiResources
IResourceStore根据ApiResource配置对象的内存中集合注册实现。
例如TestUser是用户类,他的凭据和声明在IdentityServer中。使用TestUser类似于“内存”存储的,因为它用于开发或测试。TestUser在生产环境中不要使用。
AddTestUsers
TestUserStore基于TestUser对象集合的注册。TestUserStore由默认的快速入门UI使用。还注册实现IProfileService和IResourceOwnerPasswordValidator。
4.添加服务
-
AddExtensionGrantValidator
添加IExtensionGrantValidator实现以用于扩展授权。 -
AddSecretParser
添加ISecretParser用于解析客户端或API资源凭据的实现。 -
AddSecretValidator
添加ISecretValidator用于针对凭证存储验证客户端或API资源凭证的实现。 -
AddResourceOwnerValidator
添加IResourceOwnerPasswordValidator用于验证资源所有者密码凭据授予类型的用户凭据的实现。 -
AddProfileService
添加IProfileService用于连接到自定义用户配置文件存储的实现。的DefaultProfileService类提供了依赖于验证cookie作为权利要求中的用于在令牌发行的唯一来源的默认实现。 -
AddAuthorizeInteractionResponseGenerator
添加IAuthorizeInteractionResponseGenerator实现以在授权端点处定制逻辑,以便在必须向用户显示错误,登录,同意或任何其他自定义页面的UI时。本AuthorizeInteractionResponseGenerator类提供了一个默认的实现,因此考虑从这个现有的类派生如果需要增强现有的行为。 -
AddCustomAuthorizeRequestValidator
添加ICustomAuthorizeRequestValidator实现以在授权端点处自定义请求参数验证。 -
AddCustomTokenRequestValidator
添加ICustomTokenRequestValidator实现以在令牌端点处自定义请求参数验证。 -
AddRedirectUriValidator
添加IRedirectUriValidator实现以自定义重定向URI验证。 -
AddAppAuthRedirectUriValidator
添加一个“AppAuth”(适用于Native Apps的OAuth 2.0)兼容的重定向URI验证器(进行严格验证,但也允许带有随机端口的http://127.0.0.1)。 -
AddJwtBearerClientAuthentication
使用JWT承载断言添加对客户端身份验证的支持。
5. 缓存
IdentityServer经常使用客户端和资源配置数据。如果从数据库或其他外部存储加载此数据,则频繁重新加载相同数据可能会很昂贵。
-
AddInMemoryCaching
要使用下面描述的任何缓存,ICache<T>必须在DI中注册实现。此API注册了ICache<T>基于ASP.NET Core的默认内存实现MemoryCache。 -
AddClientStoreCache
注册一个IClientStore装饰器实现,它将维护Client配置对象的内存缓存。缓存持续时间可在``Caching配置选项上配置IdentityServerOptions。 -
AddResourceStoreCache
注册一个IResourceStore装饰器实现,它将维护内存缓存IdentityResource和ApiResource配置对象。缓存持续时间可在Caching配置选项上配置IdentityServerOptions。 -
AddCorsPolicyCache
注册ICorsPolicyService装饰器实现,该实现将维护CORS策略服务评估结果的内存缓存。缓存持续时间可在Caching配置选项上配置IdentityServerOptions。
可以进一步自定义缓存:
默认缓存依赖于ICache<T>实现。如果要自定义特定配置对象的缓存行为,可以在依赖项注入系统中替换此实现。
ICache<T>本身的默认实现依赖于.NET提供的IMemoryCache接口(和MemoryCache实现)。如果要自定义内存中缓存行为,可以替换IMemoryCache依赖项注入系统中的实现。
6.配置管道
需要通过调用以下方法将IdentityServer添加到管道,UseIdentityServer包括UseAuthentication,但是一定要注意顺序,不然就坑了
public void Configure(IApplicationBuilder app)
{
app.UseIdentityServer();
}
7. 定义身份资源
身份资源是用户的用户ID,名称或电子邮件地址等数据。标识资源具有唯一名称,您可以为其分配任意声明类型。然后,这些声明将包含在用户的身份令牌中。客户端将使用该scope参数来请求访问标识资源。
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId()
};
}
该IdentityResources类支持的规范(OpenID,电子邮件,个人资料,电话和地址)中定义的所有范围。如果要全部支持它们,可以将它们添加到支持的身份资源列表中:
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Email(),
new IdentityResources.Profile(),
new IdentityResources.Phone(),
new IdentityResources.Address()
};
}
8. 定义自定义资源
您还可以定义自定义标识资源。创建一个新的IdentityResource类,为其指定名称和可选的显示名称和描述,并定义在请求此资源时应将哪些用户声明包含在标识令牌中:
public static IEnumerable<IdentityResource> GetIdentityResources()
{
var customProfile = new IdentityResource(
name: "custom.profile",
displayName: "Custom profile",
claimTypes: new[] { "name", "email", "status" });
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
customProfile
};
}
9.定义API资源
要允许客户端请求API的访问令牌,需要定义API资源,要获取API的访问权限,还需要将它们注册为范围。这次范围类型是Resource类型:
public static IEnumerable<ApiResource> GetApis()
{
return new[]
{
// simple API with a single scope (in this case the scope name is the same as the api name)
new ApiResource("api1", "Some API 1"),
// expanded version if more control is needed
new ApiResource
{
Name = "api2",
// secret for using introspection endpoint
ApiSecrets =
{
new Secret("secret".Sha256())
},
// include the following using claims in access token (in addition to subject id)
UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.Email },
// this API defines two scopes
Scopes =
{
new Scope()
{
Name = "api2.full_access",
DisplayName = "Full access to API 2",
},
new Scope
{
Name = "api2.read_only",
DisplayName = "Read only access to API 2"
}
}
}
};
}