Browse Source

feat(seed): Optimize data seeds

- 优化OpenIddict数据种子
- 增加身份标识数据种子
pull/1416/head
colin 2 months ago
parent
commit
656db9f616
  1. 309
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/DataSeeder/AuthServerDataSeedContributor.cs
  2. 330
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/DataSeeder/OpenIddictDataSeederContributor.cs
  3. 89
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/IdentityClaimTypeDataSeedContributor.cs
  4. 2
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/IdentityDataSeedContributor.cs
  5. 156
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/OpenIddictDataSeederContributor.cs
  6. 2
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/RolePermissionDataSeedContributor.cs

309
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/DataSeeder/AuthServerDataSeedContributor.cs

@ -1,309 +0,0 @@
using Microsoft.Extensions.Configuration;
using OpenIddict.Abstractions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.OpenIddict.Applications;
using Volo.Abp.OpenIddict.Scopes;
using Volo.Abp.PermissionManagement;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeder;
public class AuthServerDataSeedContributor : IDataSeedContributor, ITransientDependency
{
public static HashSet<string> InitializeScopes = new HashSet<string>
{
// obsolete! microservice should be allocated separately
"lingyun-abp-application",
// admin service
"ams",
// identity service
"ids",
// localization service
"lts",
// platform service
"pts",
// message service
"mgs",
// task service
"tks",
// webhook service
"wks",
// workflow service
"wfs",
// wechat service
"was"
};
private readonly IConfiguration _configuration;
private readonly ICurrentTenant _currentTenant;
private readonly IOpenIddictApplicationManager _applicationManager;
private readonly IOpenIddictApplicationRepository _applicationRepository;
private readonly IPermissionDataSeeder _permissionDataSeeder;
private readonly IOpenIddictScopeManager _scopeManager;
private readonly IOpenIddictScopeRepository _scopeRepository;
public AuthServerDataSeedContributor(
IConfiguration configuration,
ICurrentTenant currentTenant,
IOpenIddictScopeManager scopeManager,
IOpenIddictScopeRepository scopeRepository,
IPermissionDataSeeder permissionDataSeeder,
IOpenIddictApplicationManager applicationManager,
IOpenIddictApplicationRepository applicationRepository)
{
_configuration = configuration;
_currentTenant = currentTenant;
_scopeManager = scopeManager;
_scopeRepository = scopeRepository;
_permissionDataSeeder = permissionDataSeeder;
_applicationManager = applicationManager;
_applicationRepository = applicationRepository;
}
public async Task SeedAsync(DataSeedContext context)
{
using (_currentTenant.Change(context.TenantId))
{
await CreateScopeAsync(InitializeScopes);
await CreateApplicationAsync(InitializeScopes);
}
}
private async Task CreateScopeAsync(IEnumerable<string> scopes)
{
foreach (var scope in scopes)
{
if (await _scopeRepository.FindByNameAsync(scope) == null)
{
await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor()
{
Name = scope,
DisplayName = scope + " access",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "Abp API 应用程序访问",
[CultureInfo.GetCultureInfo("en")] = "Abp API Application Access"
},
Resources =
{
scope
}
});
}
}
}
private async Task CreateApplicationAsync(IEnumerable<string> scopes)
{
var configurationSection = _configuration.GetSection("OpenIddict:Applications");
var vueClientId = configurationSection["VueAdmin:ClientId"];
if (!vueClientId.IsNullOrWhiteSpace())
{
var vueClientRootUrl = configurationSection["VueAdmin:RootUrl"].EnsureEndsWith('/');
if (await _applicationRepository.FindByClientIdAsync(vueClientId) == null)
{
var application = new OpenIddictApplicationDescriptor
{
ClientId = vueClientId,
ClientSecret = configurationSection["VueAdmin:ClientSecret"],
ApplicationType = OpenIddictConstants.ApplicationTypes.Web,
ConsentType = OpenIddictConstants.ConsentTypes.Explicit,
DisplayName = "Abp Vue Admin Client",
PostLogoutRedirectUris =
{
new Uri(vueClientRootUrl + "signout-callback"),
new Uri(vueClientRootUrl)
},
RedirectUris =
{
new Uri(vueClientRootUrl + "signin-callback"),
new Uri(vueClientRootUrl)
},
Permissions =
{
OpenIddictConstants.Permissions.Endpoints.Authorization,
OpenIddictConstants.Permissions.Endpoints.Token,
OpenIddictConstants.Permissions.Endpoints.DeviceAuthorization,
OpenIddictConstants.Permissions.Endpoints.Introspection,
OpenIddictConstants.Permissions.Endpoints.Revocation,
OpenIddictConstants.Permissions.Endpoints.EndSession,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
OpenIddictConstants.Permissions.GrantTypes.Implicit,
OpenIddictConstants.Permissions.GrantTypes.Password,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken,
OpenIddictConstants.Permissions.GrantTypes.DeviceCode,
OpenIddictConstants.Permissions.GrantTypes.ClientCredentials,
OpenIddictConstants.Permissions.ResponseTypes.Code,
OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken,
OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken,
OpenIddictConstants.Permissions.ResponseTypes.CodeToken,
OpenIddictConstants.Permissions.ResponseTypes.IdToken,
OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken,
OpenIddictConstants.Permissions.ResponseTypes.None,
OpenIddictConstants.Permissions.ResponseTypes.Token,
OpenIddictConstants.Permissions.Scopes.Roles,
OpenIddictConstants.Permissions.Scopes.Profile,
OpenIddictConstants.Permissions.Scopes.Email,
OpenIddictConstants.Permissions.Scopes.Address,
OpenIddictConstants.Permissions.Scopes.Phone,
}
};
foreach (var scope in scopes)
{
application.Permissions.AddIfNotContains(OpenIddictConstants.Permissions.Prefixes.Scope + scope);
}
await _applicationManager.CreateAsync(application);
var vueClientPermissions = new string[1]
{
"AbpIdentity.UserLookup"
};
await _permissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, vueClientId, vueClientPermissions);
}
}
var internalServiceClientId = configurationSection["InternalService:ClientId"];
if (!internalServiceClientId.IsNullOrWhiteSpace())
{
if (await _applicationRepository.FindByClientIdAsync(internalServiceClientId) == null)
{
var application = new OpenIddictApplicationDescriptor
{
ClientId = internalServiceClientId,
ClientSecret = configurationSection["InternalService:ClientSecret"],
ClientType = OpenIddictConstants.ClientTypes.Confidential,
ConsentType = OpenIddictConstants.ConsentTypes.Explicit,
ApplicationType = OpenIddictConstants.ApplicationTypes.Native,
DisplayName = "Abp Vue Admin Client",
Permissions =
{
OpenIddictConstants.Permissions.Endpoints.Authorization,
OpenIddictConstants.Permissions.Endpoints.Token,
OpenIddictConstants.Permissions.Endpoints.DeviceAuthorization,
OpenIddictConstants.Permissions.Endpoints.Introspection,
OpenIddictConstants.Permissions.Endpoints.Revocation,
OpenIddictConstants.Permissions.Endpoints.EndSession,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
OpenIddictConstants.Permissions.GrantTypes.Implicit,
OpenIddictConstants.Permissions.GrantTypes.Password,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken,
OpenIddictConstants.Permissions.GrantTypes.DeviceCode,
OpenIddictConstants.Permissions.GrantTypes.ClientCredentials,
OpenIddictConstants.Permissions.ResponseTypes.Code,
OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken,
OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken,
OpenIddictConstants.Permissions.ResponseTypes.CodeToken,
OpenIddictConstants.Permissions.ResponseTypes.IdToken,
OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken,
OpenIddictConstants.Permissions.ResponseTypes.None,
OpenIddictConstants.Permissions.ResponseTypes.Token,
OpenIddictConstants.Permissions.Scopes.Roles,
OpenIddictConstants.Permissions.Scopes.Profile,
OpenIddictConstants.Permissions.Scopes.Email,
OpenIddictConstants.Permissions.Scopes.Address,
OpenIddictConstants.Permissions.Scopes.Phone,
}
};
foreach (var scope in scopes)
{
application.Permissions.AddIfNotContains(OpenIddictConstants.Permissions.Prefixes.Scope + scope);
}
await _applicationManager.CreateAsync(application);
var internalServicePermissions = new string[2]
{
"AbpIdentity.UserLookup","AbpIdentity.Users"
};
await _permissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, internalServiceClientId, internalServicePermissions);
}
}
var oauthClientId = configurationSection["VueOAuthClient:ClientId"];
if (!oauthClientId.IsNullOrWhiteSpace())
{
var oauthClientRootUrls = configurationSection.GetSection("VueOAuthClient:RootUrls").Get<List<string>>();
if (await _applicationRepository.FindByClientIdAsync(oauthClientId) == null)
{
var application = new OpenIddictApplicationDescriptor
{
ClientId = oauthClientId,
ClientSecret = null,
ApplicationType = OpenIddictConstants.ApplicationTypes.Web,
ConsentType = OpenIddictConstants.ConsentTypes.Implicit,
DisplayName = "OAuth Client",
PostLogoutRedirectUris = { },
RedirectUris = { },
Permissions =
{
OpenIddictConstants.Permissions.Endpoints.Authorization,
OpenIddictConstants.Permissions.Endpoints.Token,
OpenIddictConstants.Permissions.Endpoints.DeviceAuthorization,
OpenIddictConstants.Permissions.Endpoints.Introspection,
OpenIddictConstants.Permissions.Endpoints.Revocation,
OpenIddictConstants.Permissions.Endpoints.EndSession,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken,
OpenIddictConstants.Permissions.ResponseTypes.Code,
OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken,
OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken,
OpenIddictConstants.Permissions.ResponseTypes.CodeToken,
OpenIddictConstants.Permissions.ResponseTypes.IdToken,
OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken,
OpenIddictConstants.Permissions.ResponseTypes.None,
OpenIddictConstants.Permissions.ResponseTypes.Token,
OpenIddictConstants.Permissions.Scopes.Roles,
OpenIddictConstants.Permissions.Scopes.Profile,
OpenIddictConstants.Permissions.Scopes.Email,
OpenIddictConstants.Permissions.Scopes.Address,
OpenIddictConstants.Permissions.Scopes.Phone,
}
};
foreach (var scope in scopes)
{
application.Permissions.AddIfNotContains(OpenIddictConstants.Permissions.Prefixes.Scope + scope);
}
oauthClientRootUrls.ForEach(url =>
{
application.PostLogoutRedirectUris.AddIfNotContains(new Uri(url.EnsureEndsWith('/')));
application.PostLogoutRedirectUris.AddIfNotContains(new Uri(url.EnsureEndsWith('/') + "signout-callback"));
application.RedirectUris.AddIfNotContains(new Uri(url));
application.RedirectUris.AddIfNotContains(new Uri(url.EnsureEndsWith('/') + "signin-callback"));
application.RedirectUris.AddIfNotContains(new Uri(url.EnsureEndsWith('/') + "swagger/oauth2-redirect.html"));
});
await _applicationManager.CreateAsync(application);
var oauthClientPermissions = new string[1]
{
"AbpIdentity.UserLookup"
};
await _permissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, oauthClientId, oauthClientPermissions);
}
}
}
}

330
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/DataSeeder/OpenIddictDataSeederContributor.cs

@ -0,0 +1,330 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using OpenIddict.Abstractions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.OpenIddict;
using Volo.Abp.OpenIddict.Applications;
using Volo.Abp.OpenIddict.Scopes;
using Volo.Abp.PermissionManagement;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeder;
public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase, IDataSeedContributor, ITransientDependency
{
public ILogger<OpenIddictDataSeederContributor> Logger { protected get; set; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }
public OpenIddictDataSeederContributor(
IConfiguration configuration,
IOpenIddictApplicationRepository openIddictApplicationRepository,
IAbpApplicationManager applicationManager,
IOpenIddictScopeRepository openIddictScopeRepository,
IOpenIddictScopeManager scopeManager,
IPermissionDataSeeder permissionDataSeeder)
: base(configuration, openIddictApplicationRepository, applicationManager, openIddictScopeRepository, scopeManager)
{
PermissionDataSeeder = permissionDataSeeder;
Logger = NullLogger<OpenIddictDataSeederContributor>.Instance;
}
public async virtual Task SeedAsync(DataSeedContext context)
{
if (context.TenantId.HasValue)
{
return;
}
var scope = "lingyun-abp-application";
Logger.LogInformation("Seeding the default scope...");
await CreateDefaultScopeAsync();
await CreateApiScopeAsync(scope);
Logger.LogInformation("Seeding the default applications...");
await CreateApplicationAsync(scope);
Logger.LogInformation("Seeding default applications completed.");
}
private async Task CreateDefaultScopeAsync()
{
// OpenID Connect核心scope - 用于标识这是一个OIDC请求
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.OpenId,
DisplayName = "OpenID Connect", // 友好的显示名称
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "身份认证",
[CultureInfo.GetCultureInfo("en")] = "OpenID Connect"
},
Description = "使用OpenID Connect协议进行身份验证",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序使用您的身份信息进行登录",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to authenticate you using OpenID Connect"
}
});
// Profile scope - 用户基本信息
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Profile,
DisplayName = "个人资料",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "个人资料",
[CultureInfo.GetCultureInfo("en")] = "Profile"
},
Description = "访问您的基本个人资料信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的姓名、头像等基本信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your basic profile information like name and picture"
}
});
// Email scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Email,
DisplayName = "电子邮件",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "电子邮件",
[CultureInfo.GetCultureInfo("en")] = "Email"
},
Description = "访问您的电子邮件地址",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的电子邮件地址",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your email address"
}
});
// Phone scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Phone,
DisplayName = "电话号码",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "电话号码",
[CultureInfo.GetCultureInfo("en")] = "Phone"
},
Description = "访问您的电话号码",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的电话号码",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your phone number"
}
});
// Address scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Address,
DisplayName = "地址信息",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "地址信息",
[CultureInfo.GetCultureInfo("en")] = "Address"
},
Description = "访问您的地址信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的地址信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your address information"
}
});
// Roles scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Roles,
DisplayName = "角色信息",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "角色信息",
[CultureInfo.GetCultureInfo("en")] = "Roles"
},
Description = "访问您的角色信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的角色和权限信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your roles and permissions"
}
});
// Offline Access scope - 用于获取刷新令牌
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.OfflineAccess,
DisplayName = "离线访问",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "离线访问",
[CultureInfo.GetCultureInfo("en")] = "Offline Access"
},
Description = "在您未登录时访问您的信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序在您未登录时访问您的信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your information while you are offline"
}
});
}
private async Task CreateApiScopeAsync(string scope)
{
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = scope,
DisplayName = "微服务访问授权",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "微服务访问授权",
[CultureInfo.GetCultureInfo("en")] = "Single Applications"
},
Description = "适用于微服务体系的接口授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序使用各微服务模块的接口",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to use the interfaces of each microservice module"
},
Resources =
{
"api-gateway",
"auth-server",
"admin-service",
"identity-service",
"localization-service",
"message-service",
"platform-service",
"task-service",
"webhook-service",
"wechat-service",
"workflow-service",
}
});
}
private async Task CreateApplicationAsync(string scope)
{
var configurationSection = Configuration.GetSection("OpenIddict:Applications");
var vueClientId = configurationSection["VueAdmin:ClientId"];
if (!vueClientId.IsNullOrWhiteSpace())
{
Logger.LogInformation("Seeding application {vueClientId}...", vueClientId);
var vueClientRootUrls = configurationSection.GetSection("VueAdmin:RootUrls").Get<List<string>>() ?? [];
var vueClientRedirectUrls = new List<string>();
var vueClientPostLogoutRedirectUrls = new List<string>();
vueClientRootUrls.ForEach(url =>
{
vueClientRedirectUrls.Add(url.EnsureEndsWith('/'));
vueClientRedirectUrls.Add(url.EnsureEndsWith('/') + "signin-callback");
vueClientPostLogoutRedirectUrls.Add(url.EnsureEndsWith('/'));
vueClientPostLogoutRedirectUrls.Add(url.EnsureEndsWith('/') + "signout-callback");
});
await CreateOrUpdateApplicationAsync(
OpenIddictConstants.ApplicationTypes.Web,
vueClientId,
OpenIddictConstants.ClientTypes.Confidential,
OpenIddictConstants.ConsentTypes.Explicit,
"Abp Vue Admin Client",
configurationSection["VueAdmin:ClientSecret"] ?? "1q2w3e*",
[OpenIddictConstants.GrantTypes.AuthorizationCode,
OpenIddictConstants.GrantTypes.Implicit,
OpenIddictConstants.GrantTypes.Password,
OpenIddictConstants.GrantTypes.RefreshToken],
[OpenIddictConstants.Scopes.OpenId,
OpenIddictConstants.Scopes.Email,
OpenIddictConstants.Scopes.Roles,
OpenIddictConstants.Scopes.Address,
OpenIddictConstants.Scopes.Phone,
OpenIddictConstants.Scopes.Profile,
OpenIddictConstants.Scopes.OfflineAccess,
scope],
vueClientRedirectUrls,
vueClientPostLogoutRedirectUrls);
var vueClientPermissions = new string[1]
{
"AbpIdentity.UserLookup"
};
await PermissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, vueClientId, vueClientPermissions);
}
var internalServiceClientId = configurationSection["InternalService:ClientId"];
if (!internalServiceClientId.IsNullOrWhiteSpace())
{
Logger.LogInformation("Seeding application {internalServiceClientId}...", internalServiceClientId);
await CreateOrUpdateApplicationAsync(
OpenIddictConstants.ApplicationTypes.Native,
internalServiceClientId,
OpenIddictConstants.ClientTypes.Confidential,
OpenIddictConstants.ConsentTypes.Explicit,
"Abp Internal Service Client",
configurationSection["InternalService:ClientSecret"] ?? "1q2w3e*",
[OpenIddictConstants.GrantTypes.ClientCredentials],
[OpenIddictConstants.ResponseTypes.Token, scope]);
}
var oauthClientId = configurationSection["VueOAuthClient:ClientId"];
if (!oauthClientId.IsNullOrWhiteSpace())
{
Logger.LogInformation("Seeding application {oauthClientId}...", oauthClientId);
var oauthClientRootUrls = configurationSection.GetSection("VueOAuthClient:RootUrls").Get<List<string>>() ?? [];
var oauthClientRedirectUrls = new List<string>();
var oauthClientPostLogoutRedirectUrls = new List<string>();
oauthClientRootUrls.ForEach(url =>
{
oauthClientRedirectUrls.Add(url.EnsureEndsWith('/'));
oauthClientRedirectUrls.Add(url.EnsureEndsWith('/') + "signin-callback");
oauthClientRedirectUrls.Add(url.EnsureEndsWith('/') + "swagger/oauth2-redirect.html");
oauthClientPostLogoutRedirectUrls.Add(url.EnsureEndsWith('/'));
oauthClientPostLogoutRedirectUrls.Add(url.EnsureEndsWith('/') + "signout-callback");
});
await CreateOrUpdateApplicationAsync(
OpenIddictConstants.ApplicationTypes.Web,
oauthClientId,
OpenIddictConstants.ClientTypes.Public,
OpenIddictConstants.ConsentTypes.Implicit,
"Abp OAuth Client",
null,
[OpenIddictConstants.GrantTypes.AuthorizationCode,
OpenIddictConstants.GrantTypes.RefreshToken],
[OpenIddictConstants.Scopes.OpenId,
OpenIddictConstants.Scopes.Email,
OpenIddictConstants.Scopes.Roles,
OpenIddictConstants.Scopes.Address,
OpenIddictConstants.Scopes.Phone,
OpenIddictConstants.Scopes.Profile,
OpenIddictConstants.Scopes.OfflineAccess,
scope],
oauthClientRedirectUrls,
oauthClientPostLogoutRedirectUrls);
var oauthClientPermissions = new string[1]
{
"AbpIdentity.UserLookup"
};
await PermissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, oauthClientId, oauthClientPermissions);
}
}
}

89
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/IdentityClaimTypeDataSeedContributor.cs

@ -0,0 +1,89 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.DataSeeder;
public class IdentityClaimTypeDataSeedContributor : IDataSeedContributor, ITransientDependency
{
public ILogger<IdentityClaimTypeDataSeedContributor> Logger { protected get; set; }
protected IGuidGenerator GuidGenerator { get; }
protected IdentityClaimTypeManager IdentityClaimTypeManager { get; }
protected IIdentityClaimTypeRepository IdentityClaimTypeRepository { get; }
public IdentityClaimTypeDataSeedContributor(
IGuidGenerator guidGenerator,
IdentityClaimTypeManager identityClaimTypeManager,
IIdentityClaimTypeRepository identityClaimTypeRepository)
{
GuidGenerator = guidGenerator;
IdentityClaimTypeManager = identityClaimTypeManager;
IdentityClaimTypeRepository = identityClaimTypeRepository;
}
public async virtual Task SeedAsync(DataSeedContext context)
{
if (context.TenantId.HasValue)
{
return;
}
Logger.LogInformation("Seeding the default identity claim types...");
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Address);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Birthdate, valueType: IdentityClaimValueType.DateTime);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Country);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Email);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.EmailVerified, valueType: IdentityClaimValueType.Boolean);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.FamilyName);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Gender);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.GivenName);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Locale);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Locality);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.MiddleName);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Name);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Nickname);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PhoneNumber);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PhoneNumberVerified, valueType: IdentityClaimValueType.Boolean);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Picture);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PostalCode);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PreferredUsername);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Profile);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Region);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Role);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.StreetAddress);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Username);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Website);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Zoneinfo);
Logger.LogInformation("Seeding default identity claim types completed.");
}
private async Task CreateIdentityClaimTypeAsync(
[NotNull] string name,
bool required = false,
bool isStatic = false,
[CanBeNull] string regex = null,
[CanBeNull] string regexDescription = null,
[CanBeNull] string description = null,
IdentityClaimValueType valueType = IdentityClaimValueType.String)
{
if (!await IdentityClaimTypeRepository.AnyAsync(name))
{
await IdentityClaimTypeManager.CreateAsync(
new IdentityClaimType(
GuidGenerator.Create(),
name,
required,
isStatic,
regex,
regexDescription,
description,
valueType));
}
}
}

2
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/IdentityDataSeedContributor.cs

@ -48,6 +48,8 @@ public class IdentityDataSeedContributor : IDataSeedContributor, ITransientDepen
IsStatic = true,
});
}
Logger.LogInformation("Seeding default role Users completed.");
}
}
}

156
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/OpenIddictDataSeederContributor.cs

@ -18,7 +18,6 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.DataSeeder;
public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase, IDataSeedContributor, ITransientDependency
{
public ILogger<OpenIddictDataSeederContributor> Logger { protected get; set; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }
public OpenIddictDataSeederContributor(
IConfiguration configuration,
@ -36,29 +35,172 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
public async virtual Task SeedAsync(DataSeedContext context)
{
if (context.TenantId.HasValue)
{
return;
}
var scope = "lingyun-abp-application";
Logger.LogInformation("Seeding the default scope...");
await CreateScopeAsync(scope);
await CreateDefaultScopeAsync();
await CreateApiScopeAsync(scope, "all_in_one");
Logger.LogInformation("Seeding the default applications...");
await CreateApplicationAsync(scope);
Logger.LogInformation("Seeding default applications completed.");
}
private async Task CreateScopeAsync(string scope)
private async Task CreateDefaultScopeAsync()
{
// OpenID Connect核心scope - 用于标识这是一个OIDC请求
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.OpenId,
DisplayName = "OpenID Connect", // 友好的显示名称
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "身份认证",
[CultureInfo.GetCultureInfo("en")] = "OpenID Connect"
},
Description = "使用OpenID Connect协议进行身份验证",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序使用您的身份信息进行登录",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to authenticate you using OpenID Connect"
}
});
// Profile scope - 用户基本信息
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Profile,
DisplayName = "个人资料",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "个人资料",
[CultureInfo.GetCultureInfo("en")] = "Profile"
},
Description = "访问您的基本个人资料信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的姓名、头像等基本信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your basic profile information like name and picture"
}
});
// Email scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Email,
DisplayName = "电子邮件",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "电子邮件",
[CultureInfo.GetCultureInfo("en")] = "Email"
},
Description = "访问您的电子邮件地址",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的电子邮件地址",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your email address"
}
});
// Phone scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Phone,
DisplayName = "电话号码",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "电话号码",
[CultureInfo.GetCultureInfo("en")] = "Phone"
},
Description = "访问您的电话号码",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的电话号码",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your phone number"
}
});
// Address scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Address,
DisplayName = "地址信息",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "地址信息",
[CultureInfo.GetCultureInfo("en")] = "Address"
},
Description = "访问您的地址信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的地址信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your address information"
}
});
// Roles scope
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Roles,
DisplayName = "角色信息",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "角色信息",
[CultureInfo.GetCultureInfo("en")] = "Roles"
},
Description = "访问您的角色信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序访问您的角色和权限信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your roles and permissions"
}
});
// Offline Access scope - 用于获取刷新令牌
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.OfflineAccess,
DisplayName = "离线访问",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "离线访问",
[CultureInfo.GetCultureInfo("en")] = "Offline Access"
},
Description = "在您未登录时访问您的信息",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序在您未登录时访问您的信息",
[CultureInfo.GetCultureInfo("en")] = "Allow the application to access your information while you are offline"
}
});
}
private async Task CreateApiScopeAsync(string scope, string apiResource)
{
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = scope,
DisplayName = scope + " access",
DisplayName = "Single Applications",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "Abp API 应用程序访问",
[CultureInfo.GetCultureInfo("en")] = "Abp API Application Access"
[CultureInfo.GetCultureInfo("zh-Hans")] = "单体应用程序",
[CultureInfo.GetCultureInfo("en")] = "Single Applications"
},
Description = "适用于单体应用程序的接口授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序使用单体应用程序的接口",
[CultureInfo.GetCultureInfo("en")] = "Allow applications to use the interface of monolithic applications"
},
Resources =
{
scope
apiResource,
"http://localhost:30000",
}
});
}

2
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/DataSeeder/RolePermissionDataSeedContributor.cs

@ -48,6 +48,8 @@ public class RolePermissionDataSeedContributor : IDataSeedContributor, ITransien
"Users",
new string[] { "Platform.Feedback.Create" },
context.TenantId);
Logger.LogInformation("Seeding new tenant admin role permissions completed.");
}
}
}

Loading…
Cancel
Save