using Duende.IdentityServer; using Duende.IdentityServer.Models; using IdentityModel; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using ZeroFramework.IdentityServer.API.Constants; using ZeroFramework.IdentityServer.API.Tenants; namespace ZeroFramework.IdentityServer.API.IdentityStores { public static class SampleDatas { public static IEnumerable Ids => new List { new IdentityResources.OpenId(), new IdentityResources.Profile(), new("userinfo", "Your user information", new [] { JwtClaimTypes.Role, JwtRegisteredClaimNames.UniqueName, JwtClaimTypes.NickName, JwtClaimTypes.Address, JwtClaimTypes.Email }) }; public static IEnumerable Apis => new List { new("devicecenterapi", "Device Center API",new []{ JwtClaimTypes.Email }) { Scopes= { "openapi", "devicecenter" } }, new("identityserverapi", "Identity Server API",new []{ JwtClaimTypes.PhoneNumber,JwtClaimTypes.BirthDate}) { Scopes= { "openapi", "identityserver" } } }; public static IEnumerable ApiScopes => new List { new("openapi", "All open web api", new []{ JwtClaimTypes.Role, TenantClaimTypes.TenantId, TenantClaimTypes.TenantName, JwtClaimTypes.Name}), new("identityserver", "Identity server api", new []{ JwtClaimTypes.Role, TenantClaimTypes.TenantId, TenantClaimTypes.TenantName, JwtClaimTypes.Name}), new("devicecenter", "Device center api", new []{ JwtClaimTypes.Role, TenantClaimTypes.TenantId, TenantClaimTypes.TenantName, JwtClaimTypes.Name}) }; public static IEnumerable Clients => new List { new() { ClientId = "devicecenterswagger", ClientName = "Device Center Swagger", ClientSecrets = { new Secret("secret".Sha256())}, AllowedGrantTypes = GrantTypes.Code, AllowAccessTokensViaBrowser = true, RequireClientSecret=false, AlwaysSendClientClaims=true, AlwaysIncludeUserClaimsInIdToken=true, RequireConsent = false, RedirectUris = { "https://localhost:6001/swagger/oauth2-redirect.html", "https://devicecenterapi.helloworldnet.com/swagger/oauth2-redirect.html" }, PostLogoutRedirectUris = { "https://localhost:6001/swagger", "https://devicecenterapi.helloworldnet.com/swagger" }, AllowOfflineAccess=true, RequirePkce = true, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "devicecenter" }, AllowedCorsOrigins = { "https://localhost:6001", "https://devicecenterapi.helloworldnet.com" }, AccessTokenLifetime =3600*24 }, new() { ClientId = "identityserverswagger", ClientName = "Identity Server Swagger", ClientSecrets = { new Secret("secret".Sha256())}, AllowedGrantTypes = GrantTypes.Code, AllowAccessTokensViaBrowser = true, RequireClientSecret=false, AlwaysSendClientClaims=true, AlwaysIncludeUserClaimsInIdToken=true, RequireConsent = false, RedirectUris = { "https://localhost:5001/swagger/oauth2-redirect.html", "https://identityserver.helloworldnet.com/swagger/oauth2-redirect.html" }, PostLogoutRedirectUris = { "https://localhost:5001/swagger", "https://identityserver.helloworldnet.com/swagger" }, AllowOfflineAccess=true, RequirePkce = true, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "identityserver" }, AllowedCorsOrigins = { "https://localhost:5001", "https://identityserver.helloworldnet.com" }, AccessTokenLifetime = 3600*24 }, new() { ClientId = "devicecenterweb", ClientName = "Device Center Web", AllowedGrantTypes = GrantTypes.Code, AllowAccessTokensViaBrowser = true, RequireClientSecret=false, AlwaysSendClientClaims=true, AlwaysIncludeUserClaimsInIdToken=true, RequireConsent = false, RedirectUris = { "http://localhost:8000/authorization/login-callback", "https://cloud.helloworldnet.com/authorization/login-callback" }, PostLogoutRedirectUris = { "http://localhost:8000/authorization/logout-callback", "https://cloud.helloworldnet.com/authorization/logout-callback" }, AllowOfflineAccess=true, RequirePkce = true, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "userinfo", "openapi", "identityserver", "devicecenter" }, AllowedCorsOrigins = { "http://localhost:8000", "https://cloud.helloworldnet.com" }, AccessTokenLifetime = 3600*24 } }; public static IEnumerable Tenants() { Random random = new(Environment.TickCount); var result = new List(); for (int i = 1; i < 3; i++) { result.Add(new IdentityTenant() { Id = Guid.Parse($"5f6f2110-58b6-4cf9-b416-85820ba12c0{i}"), Name = $"tenant{i}", CreationTime = DateTime.Now.AddMinutes(-random.Next(0, 10000)), NormalizedName = $"tenant{i}".ToUpper(), DisplayName = $"公司租户{i}" }); } return result; } public static IEnumerable Roles() { var result = new List(); var tenants = Tenants().ToArray(); result.Add(new ApplicationRole { Name = AuthorizeConstants.TenantOwnerRequireRole, TenantId = null, TenantRoleName = AuthorizeConstants.TenantOwnerRequireRole, DisplayName = "租户所有者" }); for (int i = 1; i < 3; i++) { string tenantRoleName = $"role{i}"; result.Add(new ApplicationRole { Name = tenantRoleName, TenantId = null, TenantRoleName = tenantRoleName, DisplayName = $"宿主角色{i}" }); } for (int i = 0; i < tenants.Length; i++) { result.Add(new ApplicationRole { Name = $"{AuthorizeConstants.TenantOwnerRequireRole}@{tenants[i].Name}", TenantId = tenants[i].Id, TenantRoleName = AuthorizeConstants.TenantOwnerRequireRole, DisplayName = $"租户所有者{i}" }); for (int j = 1; j < 3; j++) { string tenantRoleName = $"role{j}"; result.Add(new ApplicationRole { Name = $"{tenantRoleName}@{tenants[i].Name}", TenantId = tenants[i].Id, TenantRoleName = tenantRoleName, DisplayName = $"租户角色{i}" }); } } return result; } public static Dictionary> Users() { var tenants = Tenants().ToArray(); var roles = Roles().ToArray(); Random random = new(Environment.TickCount); string stringMock() => $"{Path.GetRandomFileName().Replace(".", string.Empty)}"; string phoneMock() => $"{random.Next(130, 190)}{random.Next(10000000, 99999999)}"; DateTimeOffset dateMock() => DateTimeOffset.Now.AddDays(-random.Next(1, 365 * 30)); Dictionary> result = []; var currentHostRoles = roles.Where(r => r.TenantId == null).ToArray(); List claims = currentHostRoles.Select(r => new Claim(JwtClaimTypes.Role, r.Name!, ClaimValueTypes.String)).ToList(); claims.Add(new Claim(JwtClaimTypes.BirthDate, dateMock().ToString("yyyy-MM-dd"), ClaimValueTypes.Date)); var user = new ApplicationUser { UserName = "admin", PasswordHash = "guest", PhoneNumber = phoneMock(), Email = "admin@helloworldnet.com", TenantId = null, TenantUserName = "admin", DisplayName = "超级管理员" }; result[user] = claims; for (int i = 1; i < 3; i++) { IdentityTenant tenant = tenants[i - 1]; var currentTenantRoles = roles.Where(r => r.TenantId == tenant.Id).ToArray(); if (i == 2) { currentTenantRoles = currentTenantRoles.Where(r => r.TenantRoleName != AuthorizeConstants.TenantOwnerRequireRole).ToArray(); } claims = currentTenantRoles.Select(r => new Claim(JwtClaimTypes.Role, r.Name!, ClaimValueTypes.String)).ToList(); claims.Add(new Claim(JwtClaimTypes.BirthDate, dateMock().ToString("yyyy-MM-dd"), ClaimValueTypes.Date)); user = new ApplicationUser { UserName = $"guest{i}@{tenant.Name}", PasswordHash = $"guest", PhoneNumber = phoneMock(), Email = $"guest{i}@helloworldnet.com", TenantId = tenant.Id, TenantUserName = $"guest{i}", DisplayName = $"来宾访客{i}" }; result[user] = claims; } for (int i = 1; i < 100; i++) { var tenant = tenants[random.Next(0, tenants.Length)]; var currentUserRoles = roles.Where(r => r.TenantId == tenant.Id).ToArray(); string tenantUserName = $"user{i.ToString().PadLeft(2, '0')}"; claims = [ new(JwtClaimTypes.BirthDate, dateMock().ToString("yyyy-MM-dd"), ClaimValueTypes.Date), new(JwtClaimTypes.Role, currentUserRoles[random.Next(0, currentUserRoles.Length)].Name!, ClaimValueTypes.String), ]; user = new ApplicationUser { UserName = $"{tenantUserName}@{tenant.Name}", PasswordHash = tenantUserName, PhoneNumber = phoneMock(), Email = $"{stringMock()}@helloworldnet.com", TenantId = tenant.Id, TenantUserName = tenantUserName, DisplayName = $"普通用户{i.ToString().PadLeft(2, '0')}" }; result[user] = claims; } return result; } } }