预备知识: 学习Identity Server 4的预备知识
第一部分: 使用Identity Server 4建立Authorization Server (1)
第二部分: 使用Identity Server 4建立Authorization Server (2)
第三部分: 使用Identity Server 4建立Authorization Server (3)
第四部分: 使用Identity Server 4建立Authorization Server (4)
第五部分: 使用Identity Server 4建立Authorization Server (5)
由于手头目前用项目, 所以与前几篇文章不同, 这次要讲的js客户端这部分是通过我刚刚开发的真是项目的代码来讲解的.
这是后端的代码: https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplate
这里面有几个dbcontext, 需要分别对Identity Server和Sales.DataContext进行update-database, 如果使用的是Package Manager Console的话.
进行update-database的时候, 如果是针对IdentityServer这个项目的要把IdentityServer设为启动项目, 如果是针对Sales.DataContext的, 那么要把SalesApi.Web设为启动项目, 然后再进行update-database.
项目结构如图:
目前项目只用到AuthorizationServer和Sales这两部分.
首先查看AuthorizationServer的相关配置: 打开Configuration/Config.cs
ApiResource:
public static IEnumerable<ApiResource> GetApiResources() {
return new List<ApiResource> { new ApiResource(CoreApiSettings.ApiResource.Name, CoreApiSettings.ApiResource.DisplayName) { }, new ApiResource(SalesApiSettings.ApiResource.Name, SalesApiSettings.ApiResource.DisplayName) { UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.PreferredUserName, JwtClaimTypes.Email } } }; }
红色部分是相关代码, 是所需要的ApiResource的定义.
其中需要注意的是, 像user的name, email等这些claims按理说应该可以通过id_token传递给js客户端, 也就是IdentityResource应该负责的. 但是我之所以这样做是因为想把这些信息包含在access_token里面, 以便js可以使用包含这些信息的access_token去访问web api, 这样 web api就可以直接获得到当前的用户名(name), email了. 标准的做法应该是web api通过访问authorization server的user profile节点来获得用户信息, 我这么做就是图简单而已.
所以我把这几个claims添加到了ApiResource里面.
配置好整个项目之后你可以把 name 去掉试试, 如果去掉的话, 在web api的controller里面就无法取得到user的name了, 因为js收到的access token里面没有name这个claim, 所以js传给web api的token里面也没有name. 这个一定要自己修改下试试.
然后配置Client:
public static IEnumerable<Client> GetClients() {
return new List<Client> { // Core JavaScript Client new Client { ClientId = CoreApiSettings.Client.ClientId, ClientName = CoreApiSettings.Client.ClientName, AllowedGrantTypes = GrantTypes.Implicit, AllowAccessTokensViaBrowser = true, RedirectUris = { CoreApiSettings.Client.RedirectUri, CoreApiSettings.Client.SilentRedirectUri }, PostLogoutRedirectUris = { CoreApiSettings.Client.PostLogoutRedirectUris }, AllowedCorsOrigins = { CoreApiSettings.Client.AllowedCorsOrigins }, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, CoreApiSettings.ApiResource.Name } }, // Sales JavaScript Client new Client { ClientId = SalesApiSettings.Client.ClientId, ClientName = SalesApiSettings.Client.ClientName, AllowedGrantTypes = GrantTypes.Implicit, AllowAccessTokensViaBrowser = true, AccessTokenLifetime = 60 * 10, AllowOfflineAccess = true, RedirectUris = { SalesApiSettings.Client.RedirectUri, SalesApiSettings.Client.SilentRedirectUri }, PostLogoutRedirectUris = { SalesApiSettings.Client.PostLogoutRedirectUris }, AllowedCorsOrigins = { SalesApiSettings.Client.AllowedCorsOrigins }, //AlwaysIncludeUserClaimsInIdToken = true, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, SalesApiSettings.ApiResource.Name, CoreApiSettings.ApiResource.Name } } }; }
红色部分是相关的代码.
AccessTokenLifeTime是token的有效期, 单位是秒, 这里设置的是 10 分钟.
AlwaysIncludeUserClaimsInIdToken默认是false, 如果写true的话, 那么返回给客户端的id_token里面就会有user的name, email等等user相关的claims信息.
然后是IdentityResource:
public static IEnumerable<IdentityResource> GetIdentityResources() {
return