前言:
前一篇文章《.NET Core 微服务—API网关(Ocelot) 教程 [二]》已经让Ocelot和目录api(Api.Catalog)、订单api(Api.Ordering)通过网关方式运行起来了。但在日常开发中Api并不是所有人都能访问的,是添加了认证、授权的。那么本篇文章就将继续介绍Ocelot如何和 IdentityServer4 认证服务如何配合使用的。
创建认证服务(Api.IdentityServer)
1、创建一个空的WebApi项目-Api.IdentityServer,并添加IdentityServer4项目引用:如下图:
Install-Package IdentityServer4
2、要启用IdentityServer服务,不仅要把 IdentityServer 注册到容器中, 还需要配置一下内容:
- Authorization Server 保护了哪些 API (资源);
-
哪些客户端 Client(应用) 可以使用这个 Authorization Server;
-
指定可以使用 Authorization Server 授权的 Users(用户)
a) 创建文件 InMemoryConfig.cs,用于设置以上相关内容:
1 using IdentityServer4; 2 using IdentityServer4.Models; 3 using IdentityServer4.Test; 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 using System.Threading.Tasks; 8 9 namespace Api.IdentityServer 10 { 11 public class InMemoryConfig 12 { 13 public static IEnumerable<IdentityResource> GetIdentityResourceResources() 14 { 15 return new List<IdentityResource> 16 { 17 //必须要添加,否则报无效的scope错误 18 new IdentityResources.OpenId(), 19 }; 20 } 21 22 /// <summary> 23 /// api资源列表 24 /// </summary> 25 /// <returns></returns> 26 public static IEnumerable<ApiResource> GetApiResources() 27 { 28 //可访问的API资源(资源名,资源描述) 29 return new List<ApiResource> 30 { 31 new ApiResource("Api.Catalog", "Api.Catalog"), 32 new ApiResource("Api.Ordering", "Api.Ordering") 33 }; 34 } 35 36 /// <summary> 37 /// 客户端列表 38 /// </summary> 39 /// <returns></returns> 40 public static IEnumerable<Client> GetClients() 41 { 42 return new List<Client> 43 { 44 new Client 45 { 46 ClientId = "client_Catalog", //访问客户端Id,必须唯一 47 //使用客户端授权模式,客户端只需要clientid和secrets就可以访问对应的api资源。 48 AllowedGrantTypes = GrantTypes.ClientCredentials, 49 ClientSecrets = 50 { 51 new Secret("secret".Sha256()) 52 }, 53 AllowedScopes = { "Api.Catalog", IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile } 54 }, 55 new Client 56 { 57 ClientId = "client_Ordering", 58 ClientSecrets = new [] { new Secret("secret".Sha256()) }, 59 //这里使用的是通过用户名密码和ClientCredentials来换取token的方式. ClientCredentials允许Client只使用ClientSecrets来获取token. 这比较适合那种没有用户参与的api动作 60 AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials, 61 AllowedScopes = { "Api.Ordering", IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile } 62 } 63 }; 64 } 65 66 /// <summary> 67 /// 指定可以使用 Authorization Server 授权的 Users(用户) 68 /// </summary> 69 /// <returns></returns> 70 public static IEnumerable<TestUser> Users() 71 { 72 return new[] 73 { 74 new TestUser 75 { 76 SubjectId = "1", 77 Username = "cba", 78 Password = "abc" 79 } 80 }; 81 } 82 } 83 }