abp
/Data
/
OpenIddictDataSeedContributor.cs
322 строки · 12.9 Кб
1using JetBrains.Annotations;
2using Microsoft.Extensions.Localization;
3using OpenIddict.Abstractions;
4using Volo.Abp;
5using Volo.Abp.Authorization.Permissions;
6using Volo.Abp.Data;
7using Volo.Abp.DependencyInjection;
8using Volo.Abp.PermissionManagement;
9using Volo.Abp.Uow;
10
11namespace MyCompanyName.MyProjectName.Data;
12
13/* Creates initial data that is needed to property run the application
14* and make client-to-server communication possible.
15*/
16public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDependency
17{
18private readonly IConfiguration _configuration;
19private readonly IOpenIddictApplicationManager _applicationManager;
20private readonly IOpenIddictScopeManager _scopeManager;
21private readonly IPermissionDataSeeder _permissionDataSeeder;
22private readonly IStringLocalizer<OpenIddictResponse> L;
23
24public OpenIddictDataSeedContributor(
25IConfiguration configuration,
26IOpenIddictApplicationManager applicationManager,
27IOpenIddictScopeManager scopeManager,
28IPermissionDataSeeder permissionDataSeeder,
29IStringLocalizer<OpenIddictResponse> l)
30{
31_configuration = configuration;
32_applicationManager = applicationManager;
33_scopeManager = scopeManager;
34_permissionDataSeeder = permissionDataSeeder;
35L = l;
36}
37
38[UnitOfWork]
39public virtual async Task SeedAsync(DataSeedContext context)
40{
41await CreateScopesAsync();
42await CreateApplicationsAsync();
43}
44
45private async Task CreateScopesAsync()
46{
47if (await _scopeManager.FindByNameAsync("MyProjectName") == null)
48{
49await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor
50{
51Name = "MyProjectName",
52DisplayName = "MyProjectName API",
53Resources =
54{
55"MyProjectName"
56}
57});
58}
59}
60
61private async Task CreateApplicationsAsync()
62{
63var commonScopes = new List<string>
64{
65OpenIddictConstants.Permissions.Scopes.Address,
66OpenIddictConstants.Permissions.Scopes.Email,
67OpenIddictConstants.Permissions.Scopes.Phone,
68OpenIddictConstants.Permissions.Scopes.Profile,
69OpenIddictConstants.Permissions.Scopes.Roles,
70"MyProjectName"
71};
72
73var configurationSection = _configuration.GetSection("OpenIddict:Applications");
74
75//Console Test / Angular Client
76var consoleAndAngularClientId = configurationSection["MyProjectName_App:ClientId"];
77if (!consoleAndAngularClientId.IsNullOrWhiteSpace())
78{
79var webClientRootUrl = configurationSection["MyProjectName_App:RootUrl"]?.TrimEnd('/');
80await CreateApplicationAsync(
81name: consoleAndAngularClientId!,
82type: OpenIddictConstants.ClientTypes.Public,
83consentType: OpenIddictConstants.ConsentTypes.Implicit,
84displayName: "Console Test / Angular Application",
85secret: null,
86grantTypes: new List<string>
87{
88OpenIddictConstants.GrantTypes.AuthorizationCode,
89OpenIddictConstants.GrantTypes.Password,
90OpenIddictConstants.GrantTypes.ClientCredentials,
91OpenIddictConstants.GrantTypes.RefreshToken
92},
93scopes: commonScopes,
94redirectUri: webClientRootUrl,
95postLogoutRedirectUri: webClientRootUrl
96);
97}
98
99// Swagger Client
100var swaggerClientId = configurationSection["MyProjectName_Swagger:ClientId"];
101if (!swaggerClientId.IsNullOrWhiteSpace())
102{
103var swaggerRootUrl = configurationSection["MyProjectName_Swagger:RootUrl"]?.TrimEnd('/');
104
105await CreateApplicationAsync(
106name: swaggerClientId!,
107type: OpenIddictConstants.ClientTypes.Public,
108consentType: OpenIddictConstants.ConsentTypes.Implicit,
109displayName: "Swagger Application",
110secret: null,
111grantTypes: new List<string>
112{
113OpenIddictConstants.GrantTypes.AuthorizationCode,
114},
115scopes: commonScopes,
116redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html"
117);
118}
119}
120
121private async Task CreateApplicationAsync(
122[NotNull] string name,
123[NotNull] string type,
124[NotNull] string consentType,
125string displayName,
126string? secret,
127List<string> grantTypes,
128List<string> scopes,
129string? redirectUri = null,
130string? postLogoutRedirectUri = null,
131List<string>? permissions = null)
132{
133if (!string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
134{
135throw new BusinessException(L["NoClientSecretCanBeSetForPublicApplications"]);
136}
137
138if (string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
139{
140throw new BusinessException(L["TheClientSecretIsRequiredForConfidentialApplications"]);
141}
142
143if (!string.IsNullOrEmpty(name) && await _applicationManager.FindByClientIdAsync(name) != null)
144{
145return;
146//throw new BusinessException(L["TheClientIdentifierIsAlreadyTakenByAnotherApplication"]);
147}
148
149var client = await _applicationManager.FindByClientIdAsync(name);
150if (client == null)
151{
152var application = new OpenIddictApplicationDescriptor
153{
154ClientId = name,
155ClientType = type,
156ClientSecret = secret,
157ConsentType = consentType,
158DisplayName = displayName
159};
160
161Check.NotNullOrEmpty(grantTypes, nameof(grantTypes));
162Check.NotNullOrEmpty(scopes, nameof(scopes));
163
164if (new [] { OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit }.All(grantTypes.Contains))
165{
166application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken);
167
168if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
169{
170application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken);
171application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeToken);
172}
173}
174
175if (!redirectUri.IsNullOrWhiteSpace() || !postLogoutRedirectUri.IsNullOrWhiteSpace())
176{
177application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Logout);
178}
179
180var buildInGrantTypes = new []
181{
182OpenIddictConstants.GrantTypes.Implicit,
183OpenIddictConstants.GrantTypes.Password,
184OpenIddictConstants.GrantTypes.AuthorizationCode,
185OpenIddictConstants.GrantTypes.ClientCredentials,
186OpenIddictConstants.GrantTypes.DeviceCode,
187OpenIddictConstants.GrantTypes.RefreshToken
188};
189
190foreach (var grantType in grantTypes)
191{
192if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode)
193{
194application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode);
195application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Code);
196}
197
198if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || grantType == OpenIddictConstants.GrantTypes.Implicit)
199{
200application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization);
201}
202
203if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode ||
204grantType == OpenIddictConstants.GrantTypes.ClientCredentials ||
205grantType == OpenIddictConstants.GrantTypes.Password ||
206grantType == OpenIddictConstants.GrantTypes.RefreshToken ||
207grantType == OpenIddictConstants.GrantTypes.DeviceCode)
208{
209application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token);
210application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Revocation);
211application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Introspection);
212}
213
214if (grantType == OpenIddictConstants.GrantTypes.ClientCredentials)
215{
216application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials);
217}
218
219if (grantType == OpenIddictConstants.GrantTypes.Implicit)
220{
221application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit);
222}
223
224if (grantType == OpenIddictConstants.GrantTypes.Password)
225{
226application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password);
227}
228
229if (grantType == OpenIddictConstants.GrantTypes.RefreshToken)
230{
231application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken);
232}
233
234if (grantType == OpenIddictConstants.GrantTypes.DeviceCode)
235{
236application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.DeviceCode);
237application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Device);
238}
239
240if (grantType == OpenIddictConstants.GrantTypes.Implicit)
241{
242application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdToken);
243if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
244{
245application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken);
246application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Token);
247}
248}
249
250if (!buildInGrantTypes.Contains(grantType))
251{
252application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.GrantType + grantType);
253}
254}
255
256var buildInScopes = new []
257{
258OpenIddictConstants.Permissions.Scopes.Address,
259OpenIddictConstants.Permissions.Scopes.Email,
260OpenIddictConstants.Permissions.Scopes.Phone,
261OpenIddictConstants.Permissions.Scopes.Profile,
262OpenIddictConstants.Permissions.Scopes.Roles
263};
264
265foreach (var scope in scopes)
266{
267if (buildInScopes.Contains(scope))
268{
269application.Permissions.Add(scope);
270}
271else
272{
273application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.Scope + scope);
274}
275}
276
277if (redirectUri != null)
278{
279if (!redirectUri.IsNullOrEmpty())
280{
281if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString())
282{
283throw new BusinessException(L["InvalidRedirectUri", redirectUri]);
284}
285
286if (application.RedirectUris.All(x => x != uri))
287{
288application.RedirectUris.Add(uri);
289}
290}
291}
292
293if (postLogoutRedirectUri != null)
294{
295if (!postLogoutRedirectUri.IsNullOrEmpty())
296{
297if (!Uri.TryCreate(postLogoutRedirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString())
298{
299throw new BusinessException(L["InvalidPostLogoutRedirectUri", postLogoutRedirectUri]);
300}
301
302if (application.PostLogoutRedirectUris.All(x => x != uri))
303{
304application.PostLogoutRedirectUris.Add(uri);
305}
306}
307}
308
309if (permissions != null)
310{
311await _permissionDataSeeder.SeedAsync(
312ClientPermissionValueProvider.ProviderName,
313name,
314permissions,
315null
316);
317}
318
319await _applicationManager.CreateAsync(application);
320}
321}
322}
323