Identity Server通过ProfileService返回用户角色
Identity Server系列目录
- Blazor Server访问Identity Server 4单点登录 - SunnyTrudeau - 博客园 (cnblogs.com)
- Blazor Server访问Identity Server 4单点登录2-集成Asp.Net角色 - SunnyTrudeau - 博客园 (cnblogs.com)
- Blazor Server访问Identity Server 4-手机验证码登录 - SunnyTrudeau - 博客园 (cnblogs.com)
- Blazor MAUI客户端访问Identity Server登录 - SunnyTrudeau - 博客园 (cnblogs.com)
- 在Identity Server 4项目集成Blazor组件 - SunnyTrudeau - 博客园 (cnblogs.com)
- Identity Server 4退出登录自动跳转返回 - SunnyTrudeau - 博客园 (cnblogs.com)
之前采用自定义IdentityResource的方式实现了从Identity Server返回用户角色,
public static class Config
{
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource("role", new string[]{JwtClaimTypes.Role })
};
最近才发现可以通过ProfileService返回用户角色,微软官网上有相关介绍:
使用 Identity 服务器保护托管 ASP.NET Core Blazor WebAssembly 应用 | Microsoft Docs
决定改用ProfileService方案。
修改Identity Server服务端
修改AspNetId4Web认证服务器,可以照搬官网ProfileService的代码。
using IdentityModel; using IdentityServer4.Models; using IdentityServer4.Services; using System.Threading.Tasks; namespace AspNetId4Web { public class ProfileService : IProfileService { public ProfileService() { } public async Task GetProfileDataAsync(ProfileDataRequestContext context) { var nameClaim = context.Subject.FindAll(JwtClaimTypes.Name); context.IssuedClaims.AddRange(nameClaim); var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role); context.IssuedClaims.AddRange(roleClaims); await Task.CompletedTask; } public async Task IsActiveAsync(IsActiveContext context) { await Task.CompletedTask; } } }
在 Startup.cs 中注册配置文件服务:
builder.Services.AddTransient<IProfileService, ProfileService>();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
config配置客户端不需要添加role了。
new Client() { ClientId="BlazorServerOidc", ClientName = "BlazorServerOidc", ClientSecrets=new []{new Secret("BlazorServerOidc.Secret".Sha256())}, AllowedGrantTypes = GrantTypes.Code, AllowedCorsOrigins = { "https://localhost:5501" }, RedirectUris = { "https://localhost:5501/signin-oidc" }, PostLogoutRedirectUris = { "https://localhost:5501/signout-callback-oidc" }, //效果等同客户端项目配置options.GetClaimsFromUserInfoEndpoint = true //AlwaysIncludeUserClaimsInIdToken = true, //AllowedScopes = { "openid", "profile", "scope1", "role", } //通过ProfileService返回用户角色 AllowedScopes = { "openid", "profile", "scope1", } },
修改Blazor Server客户端
修改BlzOidc项目,配置oidc参数,也不再需要role了。
//指定要取哪些资料(除Profile之外,Profile是默认包含的)
options.Scope.Add("scope1");
//通过ProfileService返回用户角色
//options.Scope.Add("role");
然后在VS2022同时启动两个项目,测试可以看到BlzOidc项目登录之后可以获取到用户角色。
尝试通过ProfileService返回更多用户声明
var emailClaims = context.Subject.FindAll(JwtClaimTypes.Email);
context.IssuedClaims.AddRange(emailClaims);
var phoneNumberClaims = context.Subject.FindAll(JwtClaimTypes.PhoneNumber);
context.IssuedClaims.AddRange(phoneNumberClaims);
但是有的可以,例如email,有的不行,例如phoneNumber,也是奇怪。
DEMO代码地址:https://gitee.com/woodsun/blzid4