|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using JetBrains.Annotations;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Localization;
- using OpenIddict.Abstractions;
- using Volo.Abp;
- using Volo.Abp.Authorization.Permissions;
- using Volo.Abp.Data;
- using Volo.Abp.DependencyInjection;
- using Volo.Abp.PermissionManagement;
- using Volo.Abp.Uow;
-
- namespace Himp.TaskScheduling.OpenIddict;
-
- /* Creates initial data that is needed to property run the application
- * and make client-to-server communication possible.
- */
- public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDependency
- {
- private readonly IConfiguration _configuration;
- private readonly IOpenIddictApplicationManager _applicationManager;
- private readonly IOpenIddictScopeManager _scopeManager;
- private readonly IPermissionDataSeeder _permissionDataSeeder;
- private readonly IStringLocalizer<OpenIddictResponse> L;
-
- public OpenIddictDataSeedContributor(
- IConfiguration configuration,
- IOpenIddictApplicationManager applicationManager,
- IOpenIddictScopeManager scopeManager,
- IPermissionDataSeeder permissionDataSeeder,
- IStringLocalizer<OpenIddictResponse> l)
- {
- _configuration = configuration;
- _applicationManager = applicationManager;
- _scopeManager = scopeManager;
- _permissionDataSeeder = permissionDataSeeder;
- L = l;
- }
-
- [UnitOfWork]
- public virtual async Task SeedAsync(DataSeedContext context)
- {
- await CreateScopesAsync();
- await CreateApplicationsAsync();
- }
-
- private async Task CreateScopesAsync()
- {
- if (await _scopeManager.FindByNameAsync("TaskScheduling") == null)
- {
- await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor
- {
- Name = "TaskScheduling",
- DisplayName = "TaskScheduling API",
- Resources =
- {
- "TaskScheduling"
- }
- });
- }
- }
-
- private async Task CreateApplicationsAsync()
- {
- var commonScopes = new List<string>
- {
- OpenIddictConstants.Permissions.Scopes.Address,
- OpenIddictConstants.Permissions.Scopes.Email,
- OpenIddictConstants.Permissions.Scopes.Phone,
- OpenIddictConstants.Permissions.Scopes.Profile,
- OpenIddictConstants.Permissions.Scopes.Roles,
- "TaskScheduling"
- };
-
- var configurationSection = _configuration.GetSection("OpenIddict:Applications");
-
- //Web Client
- var webClientId = configurationSection["TaskScheduling_Web:ClientId"];
- if (!webClientId.IsNullOrWhiteSpace())
- {
- var webClientRootUrl = configurationSection["TaskScheduling_Web:RootUrl"]!.EnsureEndsWith('/');
-
- /* TaskScheduling_Web client is only needed if you created a tiered
- * solution. Otherwise, you can delete this client. */
- await CreateApplicationAsync(
- name: webClientId!,
- type: OpenIddictConstants.ClientTypes.Confidential,
- consentType: OpenIddictConstants.ConsentTypes.Implicit,
- displayName: "Web Application",
- secret: configurationSection["TaskScheduling_Web:ClientSecret"] ?? "1q2w3e*",
- grantTypes: new List<string> //Hybrid flow
- {
- OpenIddictConstants.GrantTypes.AuthorizationCode,
- OpenIddictConstants.GrantTypes.Implicit
- },
- scopes: commonScopes,
- redirectUri: $"{webClientRootUrl}signin-oidc",
- postLogoutRedirectUri: $"{webClientRootUrl}signout-callback-oidc"
- );
- }
-
- //Console Test / Angular Client
- var consoleAndAngularClientId = configurationSection["TaskScheduling_App:ClientId"];
- if (!consoleAndAngularClientId.IsNullOrWhiteSpace())
- {
- var consoleAndAngularClientRootUrl = configurationSection["TaskScheduling_App:RootUrl"]?.TrimEnd('/');
- await CreateApplicationAsync(
- name: consoleAndAngularClientId!,
- type: OpenIddictConstants.ClientTypes.Public,
- consentType: OpenIddictConstants.ConsentTypes.Implicit,
- displayName: "Console Test / Angular Application",
- secret: null,
- grantTypes: new List<string>
- {
- OpenIddictConstants.GrantTypes.AuthorizationCode,
- OpenIddictConstants.GrantTypes.Password,
- OpenIddictConstants.GrantTypes.ClientCredentials,
- OpenIddictConstants.GrantTypes.RefreshToken
- },
- scopes: commonScopes,
- redirectUri: consoleAndAngularClientRootUrl,
- postLogoutRedirectUri: consoleAndAngularClientRootUrl
- );
- }
-
- // Blazor Client
- var blazorClientId = configurationSection["TaskScheduling_Blazor:ClientId"];
- if (!blazorClientId.IsNullOrWhiteSpace())
- {
- var blazorRootUrl = configurationSection["TaskScheduling_Blazor:RootUrl"]?.TrimEnd('/');
-
- await CreateApplicationAsync(
- name: blazorClientId!,
- type: OpenIddictConstants.ClientTypes.Public,
- consentType: OpenIddictConstants.ConsentTypes.Implicit,
- displayName: "Blazor Application",
- secret: null,
- grantTypes: new List<string>
- {
- OpenIddictConstants.GrantTypes.AuthorizationCode,
- },
- scopes: commonScopes,
- redirectUri: $"{blazorRootUrl}/authentication/login-callback",
- postLogoutRedirectUri: $"{blazorRootUrl}/authentication/logout-callback"
- );
- }
-
- // Swagger Client
- var swaggerClientId = configurationSection["TaskScheduling_Swagger:ClientId"];
- if (!swaggerClientId.IsNullOrWhiteSpace())
- {
- var swaggerRootUrl = configurationSection["TaskScheduling_Swagger:RootUrl"]?.TrimEnd('/');
-
- await CreateApplicationAsync(
- name: swaggerClientId!,
- type: OpenIddictConstants.ClientTypes.Public,
- consentType: OpenIddictConstants.ConsentTypes.Implicit,
- displayName: "Swagger Application",
- secret: null,
- grantTypes: new List<string>
- {
- OpenIddictConstants.GrantTypes.AuthorizationCode,
- },
- scopes: commonScopes,
- redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html"
- );
- }
- }
-
- private async Task CreateApplicationAsync(
- [NotNull] string name,
- [NotNull] string type,
- [NotNull] string consentType,
- string displayName,
- string? secret,
- List<string> grantTypes,
- List<string> scopes,
- string? redirectUri = null,
- string? postLogoutRedirectUri = null,
- List<string>? permissions = null)
- {
- if (!string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
- {
- throw new BusinessException(L["NoClientSecretCanBeSetForPublicApplications"]);
- }
-
- if (string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
- {
- throw new BusinessException(L["TheClientSecretIsRequiredForConfidentialApplications"]);
- }
-
- if (!string.IsNullOrEmpty(name) && await _applicationManager.FindByClientIdAsync(name) != null)
- {
- return;
- //throw new BusinessException(L["TheClientIdentifierIsAlreadyTakenByAnotherApplication"]);
- }
-
- var client = await _applicationManager.FindByClientIdAsync(name);
- if (client == null)
- {
- var application = new OpenIddictApplicationDescriptor
- {
- ClientId = name,
- ClientType = type,
- ClientSecret = secret,
- ConsentType = consentType,
- DisplayName = displayName
- };
-
- Check.NotNullOrEmpty(grantTypes, nameof(grantTypes));
- Check.NotNullOrEmpty(scopes, nameof(scopes));
-
- if (new [] { OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit }.All(grantTypes.Contains))
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken);
-
- if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken);
- application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeToken);
- }
- }
-
- if (!redirectUri.IsNullOrWhiteSpace() || !postLogoutRedirectUri.IsNullOrWhiteSpace())
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Logout);
- }
-
- var buildInGrantTypes = new []
- {
- OpenIddictConstants.GrantTypes.Implicit,
- OpenIddictConstants.GrantTypes.Password,
- OpenIddictConstants.GrantTypes.AuthorizationCode,
- OpenIddictConstants.GrantTypes.ClientCredentials,
- OpenIddictConstants.GrantTypes.DeviceCode,
- OpenIddictConstants.GrantTypes.RefreshToken
- };
-
- foreach (var grantType in grantTypes)
- {
- if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode);
- application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Code);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || grantType == OpenIddictConstants.GrantTypes.Implicit)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode ||
- grantType == OpenIddictConstants.GrantTypes.ClientCredentials ||
- grantType == OpenIddictConstants.GrantTypes.Password ||
- grantType == OpenIddictConstants.GrantTypes.RefreshToken ||
- grantType == OpenIddictConstants.GrantTypes.DeviceCode)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token);
- application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Revocation);
- application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Introspection);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.ClientCredentials)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.Implicit)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.Password)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.RefreshToken)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.DeviceCode)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.DeviceCode);
- application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Device);
- }
-
- if (grantType == OpenIddictConstants.GrantTypes.Implicit)
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdToken);
- if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken);
- application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Token);
- }
- }
-
- if (!buildInGrantTypes.Contains(grantType))
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.GrantType + grantType);
- }
- }
-
- var buildInScopes = new []
- {
- OpenIddictConstants.Permissions.Scopes.Address,
- OpenIddictConstants.Permissions.Scopes.Email,
- OpenIddictConstants.Permissions.Scopes.Phone,
- OpenIddictConstants.Permissions.Scopes.Profile,
- OpenIddictConstants.Permissions.Scopes.Roles
- };
-
- foreach (var scope in scopes)
- {
- if (buildInScopes.Contains(scope))
- {
- application.Permissions.Add(scope);
- }
- else
- {
- application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.Scope + scope);
- }
- }
-
- if (redirectUri != null)
- {
- if (!redirectUri.IsNullOrEmpty())
- {
- if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString())
- {
- throw new BusinessException(L["InvalidRedirectUri", redirectUri]);
- }
-
- if (application.RedirectUris.All(x => x != uri))
- {
- application.RedirectUris.Add(uri);
- }
- }
- }
-
- if (postLogoutRedirectUri != null)
- {
- if (!postLogoutRedirectUri.IsNullOrEmpty())
- {
- if (!Uri.TryCreate(postLogoutRedirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString())
- {
- throw new BusinessException(L["InvalidPostLogoutRedirectUri", postLogoutRedirectUri]);
- }
-
- if (application.PostLogoutRedirectUris.All(x => x != uri))
- {
- application.PostLogoutRedirectUris.Add(uri);
- }
- }
- }
-
- if (permissions != null)
- {
- await _permissionDataSeeder.SeedAsync(
- ClientPermissionValueProvider.ProviderName,
- name,
- permissions,
- null
- );
- }
-
- await _applicationManager.CreateAsync(application);
- }
- }
- }
|