前言
上一篇文章<学习OIDC>介绍了OIDC协议,本篇开始我们就来具体来学习OIDC的具体实现IdentityServer4 学习。
一、IdentityServer4 是什么?
IdentityServer4是用于ASP.NET Core的OpenID Connect和OAuth 2.0框架。
可以构建(或重新使用)包含登录和注销页面的应用程序,IdentityServer中间件会向其添加必要的协议头,以便客户端应用程序可以使用这些标准协议与其对话。
可以在应用程序中使用以下功能:
-
- 身份验证即服务
所有应用程序(Web,本机,移动,服务)的集中式登录逻辑和工作流。IdentityServer是OpenID Connect 的官方认证实现
-
- 单点登录/退出
多种应用程序类型的单点登录(注销)
-
- API的访问控制
为各种类型的客户端(例如,服务器到服务器,Web应用程序,SPA和本机/移动应用程序)的API发出访问令牌
-
- 联合网关
支持外部身份提供程序,例如Azure Active Directory,Google,Facebook等。这使您的应用程序免受如何连接到这些外部提供程序的详细信息的影响。
二、简单使用示例
先创建项目目录结构(如下图)
1、IdentityServer 认证服务实现
a) 创建一个空的WebApi项目-cz.IdentityServer,并添加IdentityServer4项目引用:如下图:
Install-Package IdentityServer4
b) 要启用IdentityServer服务,不仅要把 IdentityServer 注册到容器中, 还需要配置一下内容:
-
- Authorization Server 保护了哪些 API (资源);
-
哪些客户端 Client(应用) 可以使用这个 Authorization Server;
-
指定可以使用 Authorization Server 授权的 Users(用户)
创建文件 InMemoryConfig.cs,用于设置以上相关内容:
using IdentityServer4; using IdentityServer4.Models; using IdentityServer4.Test; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace cz.IdentityServer { public class InMemoryConfig { public static IEnumerable<IdentityResource> GetIdentityResourceResources() { return new List<IdentityResource> { //必须要添加,否则报无效的scope错误 new IdentityResources.OpenId(), new IdentityResources.Profile() }; } /// <summary> /// api资源列表 /// </summary> /// <returns></returns> public static IEnumerable<ApiResource> GetApiResources() { //可访问的API资源(资源名,资源描述) return new List<ApiResource> { new ApiResource("goods", "Goods Service"), new ApiResource("order", "Order Service") }; } /// <summary> /// 客户端列表 /// </summary> /// <returns></returns> public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "clientGoods", //访问客户端Id,必须唯一 //使用客户端授权模式,客户端只需要clientid和secrets就可以访问对应的api资源。 AllowedGrantTypes = GrantTypes.ClientCredentials, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "goods", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile }, }, new Client { ClientId = "clientOrder", ClientSecrets = new [] { new Secret("secret".Sha256()) }, //这里使用的是通过用户名密码和ClientCredentials来换取token的方式. ClientCredentials允许Client只使用ClientSecrets来获取token. 这比较适合那种没有用户参与的api动作 AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials, AllowedScopes = { "order","goods", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile } } }; } /// <summary> /// 指定可以使用 Authorization Server 授权的 Users(用户) /// </summary> /// <returns></returns> public static IEnumerable<TestUser> Users() { return new[] { new TestUser { SubjectId = "1", Username = "cba", Password = "cba" }, new TestUser { SubjectId = "2", Username = "chaney", Password = "123" } }; } } }