什么是Identity Server?
Identity Server 4(IdS4)是用于.NET Core应用程序的OpenID Connect和OAuth 2.0框架。它是一种身份验证服务,可为您提供针对不同类型的应用程序(Web、移动或服务)的集中式身份验证逻辑。
在ASP.NET Core Web App中实现IdS4首先,您需要使用以下命令创建一个空的ASP.NET Core Web应用程序:
dotnet new web
或者,您可以通过使用空模板选择ASP.NET Core Web应用程序项目,从Visual Studio中实现相同目的。
现在,让我们通过安装NuGet软件包来添加IdS4。
dotnet add package IdentityServer4
您已经成功安装了IdS4软件包,现在打开项目的Startup.cs文件并在ConfigureServices()函数中添加以下代码。请记住,以下示例代码仅是一个空列表,因此您需要确保您的应用中具有有效的内存资源和客户端列表。
services.AddIdentityServer()
.AddInMemoryClients(new List())
.AddInMemoryApiResources(new List())
.AddInMemoryIdentityResources(new List())
.AddInMemoryPersistedGrants()
.AddTestUsers(new List())
.AddDeveloperSigningCredential();
上面的代码将包括IdS4依赖关系,现在您需要使用下面的代码片段更新Configure方法。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHttpsRedirection();
app.UseIdentityServer();
}
让我们了解配置,我们使用.AddDeveloperSigningCredential()扩展方法使用默认签名证书的.AddIdentityServer()添加了IdS4依赖关系。然后我们用.UseIdentityServer() 扩展方法更新了Configure()方法,这里我们实际上是启用OpenIdConnect端点。请在下面查看IdS4提供的端点列表:
- connect/token
- connect/authorize
- connect/userinfo
- connect/endsession
- connect/revocation
- connect/introspect
- connect/deviceauthorization
您可以使用/.well-known/openid-configuration端点获取可用端点的列表。
端点的上述列表由IdS4/OpenIdConnect/OAuth2框架提供。如果您需要自己的端点来满足业务需求,可以的话,您绝对可以创建自定义端点!
请按照以下步骤添加自定义端点:
- 注册自定义端点:
services.AddIdentityServer(options =>
{
//Adding custom endpoint in the discovery document
options.Discovery.ExpandRelativePathsInCustomEntries = true;
options.Discovery.CustomEntries = new Dictionary
{
{ "myCustomEndpoint", "connect/myCustomEndpoint"}
};
})
.AddEndpoint("myCustomEndpoint", "connect/myCustomEndpoint");
- 实现处理程序:
上面的代码在IdS4的端点中添加了一个自定义端点,现在您需要编写一个用于实际实现的处理程序类。
using IdentityServer4.Hosting;
public class MyCustomEndpoint : IEndpointHandler
{
public async Task ProcessAsync(HttpContext
context)
{
// ToDo: Here you can add your custom business-specific
logic
}
}
如何使用这些端点?
您可以使用这些端点从IdS4令牌提供者获取access/refresh/identity令牌,每个端点都有不同的用途,例如,connect/authorize在面向公众的应用程序中使用的端点,您可以在其中使用IdS4登录屏幕进行身份验证(使用隐式授予类型)。
同样,connect/token端点可以通过编程方式(使用密码授予类型)为您提供访问令牌。
申请Password/ResourceOwner授予类型:
POST /connect/token
Headers:
Content-Type: application/x-www-form-urlencoded
Body:
grant_type=password&scope=api1&client_id=testClient&client_secret=testSecret&
username=test.user&password=testPassword
上面的请求将为您提供accessToken,因此现在您可以使用此访问令牌与REST API请求一起传递。
您可以使用dotnet new webapi命令保护现有的API或创建一个新的API 。
为了保护您的API,您需要安装NuGet软件包。
dotnet add package IdentityServer4.AccessTokenValidation
此NuGet提供JWT和参考(Reference)令牌验证中间件,对于参考(Reference)令牌验证,它也提供缓存。要验证您的访问令牌,您需要在ConfigureService方法中添加以下代码:
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication("Bearer", options =>
{
options.ApiName = "api1";
options.Authority = "https://localhost:44385";
});
这里Authority是IdentityServer4的URL,ApiName是来自IdS4配置的访问令牌Audience和API资源名称。
要添加IdS4身份验证中间件,您需要使用以下代码更新您的Configure方法:
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseAuthorization();
}
如果您查看业务需求,经过身份验证的用户并不总是被授权访问所有资源。因此,要允许访问授权用户,您可以实现基于策略的授权。例如,如果您决定授权用户(如果该用户的accessToken包含特定范围),则可以使用.AddPolicy()方法创建简单的策略。您需要使用以下示例代码更新ConfigureServices方法。
services.AddAuthorization(option =>
{
option.AddPolicy("MyPolicy", p =>
{
p.RequireAuthenticatedUser();
p.RequireClaim(JwtClaimTypes.Scope,
new List
{
"api1.read",
"api1.write:
}
);
});
});
现在,您的API受IdS4身份验证提供程序的保护,因此,使用[Authorize]属性修饰的所有端点都将受到保护。要调用这些REST端点,您需要使用Authorization头传递一个accessToken。
GET /api/v1.0/getuser
Headers:
Authorization: Bearer
注意:我们已经在.NET项目中实现/集成了IdS4,但尚未引入用户界面,因此,要为IdS4项目添加UI,可以从QuickStart文件夹中复制粘贴代码。
在此博客中,我使用内存中的客户端和用户,这绝对不适用于生产应用程序,因此您可以使用实体框架从SQL DB更新/获取客户端/用户/资源,也可以创建自己的存储库。
祝您编码愉快!