abp

Форк
0
322 строки · 12.9 Кб
1
using JetBrains.Annotations;
2
using Microsoft.Extensions.Localization;
3
using OpenIddict.Abstractions;
4
using Volo.Abp;
5
using Volo.Abp.Authorization.Permissions;
6
using Volo.Abp.Data;
7
using Volo.Abp.DependencyInjection;
8
using Volo.Abp.PermissionManagement;
9
using Volo.Abp.Uow;
10

11
namespace 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
 */
16
public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDependency
17
{
18
    private readonly IConfiguration _configuration;
19
    private readonly IOpenIddictApplicationManager _applicationManager;
20
    private readonly IOpenIddictScopeManager _scopeManager;
21
    private readonly IPermissionDataSeeder _permissionDataSeeder;
22
    private readonly IStringLocalizer<OpenIddictResponse> L;
23

24
    public OpenIddictDataSeedContributor(
25
        IConfiguration configuration,
26
        IOpenIddictApplicationManager applicationManager,
27
        IOpenIddictScopeManager scopeManager,
28
        IPermissionDataSeeder permissionDataSeeder,
29
        IStringLocalizer<OpenIddictResponse> l)
30
    {
31
        _configuration = configuration;
32
        _applicationManager = applicationManager;
33
        _scopeManager = scopeManager;
34
        _permissionDataSeeder = permissionDataSeeder;
35
        L = l;
36
    }
37

38
    [UnitOfWork]
39
    public virtual async Task SeedAsync(DataSeedContext context)
40
    {
41
        await CreateScopesAsync();
42
        await CreateApplicationsAsync();
43
    }
44

45
    private async Task CreateScopesAsync()
46
    {
47
        if (await _scopeManager.FindByNameAsync("MyProjectName") == null)
48
        {
49
            await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor
50
            {
51
                Name = "MyProjectName",
52
                DisplayName = "MyProjectName API",
53
                Resources =
54
                {
55
                    "MyProjectName"
56
                }
57
            });
58
        }
59
    }
60

61
    private async Task CreateApplicationsAsync()
62
    {
63
        var commonScopes = new List<string>
64
        {
65
            OpenIddictConstants.Permissions.Scopes.Address,
66
            OpenIddictConstants.Permissions.Scopes.Email,
67
            OpenIddictConstants.Permissions.Scopes.Phone,
68
            OpenIddictConstants.Permissions.Scopes.Profile,
69
            OpenIddictConstants.Permissions.Scopes.Roles,
70
            "MyProjectName"
71
        };
72

73
        var configurationSection = _configuration.GetSection("OpenIddict:Applications");
74

75
        //Console Test / Angular Client
76
        var consoleAndAngularClientId = configurationSection["MyProjectName_App:ClientId"];
77
        if (!consoleAndAngularClientId.IsNullOrWhiteSpace())
78
        {
79
            var webClientRootUrl = configurationSection["MyProjectName_App:RootUrl"]?.TrimEnd('/');
80
            await CreateApplicationAsync(
81
                name: consoleAndAngularClientId!,
82
                type: OpenIddictConstants.ClientTypes.Public,
83
                consentType: OpenIddictConstants.ConsentTypes.Implicit,
84
                displayName: "Console Test / Angular Application",
85
                secret: null,
86
                grantTypes: new List<string>
87
                {
88
                    OpenIddictConstants.GrantTypes.AuthorizationCode,
89
                    OpenIddictConstants.GrantTypes.Password,
90
                    OpenIddictConstants.GrantTypes.ClientCredentials,
91
                    OpenIddictConstants.GrantTypes.RefreshToken
92
                },
93
                scopes: commonScopes,
94
                redirectUri: webClientRootUrl,
95
                postLogoutRedirectUri: webClientRootUrl
96
            );
97
        }
98

99
        // Swagger Client
100
        var swaggerClientId = configurationSection["MyProjectName_Swagger:ClientId"];
101
        if (!swaggerClientId.IsNullOrWhiteSpace())
102
        {
103
            var swaggerRootUrl = configurationSection["MyProjectName_Swagger:RootUrl"]?.TrimEnd('/');
104

105
            await CreateApplicationAsync(
106
                name: swaggerClientId!,
107
                type: OpenIddictConstants.ClientTypes.Public,
108
                consentType: OpenIddictConstants.ConsentTypes.Implicit,
109
                displayName: "Swagger Application",
110
                secret: null,
111
                grantTypes: new List<string>
112
                {
113
                    OpenIddictConstants.GrantTypes.AuthorizationCode,
114
                },
115
                scopes: commonScopes,
116
                redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html"
117
            );
118
        }
119
    }
120

121
    private async Task CreateApplicationAsync(
122
        [NotNull] string name,
123
        [NotNull] string type,
124
        [NotNull] string consentType,
125
        string displayName,
126
        string? secret,
127
        List<string> grantTypes,
128
        List<string> scopes,
129
        string? redirectUri = null,
130
        string? postLogoutRedirectUri = null,
131
        List<string>? permissions = null)
132
    {
133
        if (!string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
134
        {
135
            throw new BusinessException(L["NoClientSecretCanBeSetForPublicApplications"]);
136
        }
137

138
        if (string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
139
        {
140
            throw new BusinessException(L["TheClientSecretIsRequiredForConfidentialApplications"]);
141
        }
142

143
        if (!string.IsNullOrEmpty(name) && await _applicationManager.FindByClientIdAsync(name) != null)
144
        {
145
            return;
146
            //throw new BusinessException(L["TheClientIdentifierIsAlreadyTakenByAnotherApplication"]);
147
        }
148

149
        var client = await _applicationManager.FindByClientIdAsync(name);
150
        if (client == null)
151
        {
152
            var application = new OpenIddictApplicationDescriptor
153
            {
154
                ClientId = name,
155
                ClientType = type,
156
                ClientSecret = secret,
157
                ConsentType = consentType,
158
                DisplayName = displayName
159
            };
160

161
            Check.NotNullOrEmpty(grantTypes, nameof(grantTypes));
162
            Check.NotNullOrEmpty(scopes, nameof(scopes));
163

164
            if (new [] { OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit }.All(grantTypes.Contains))
165
            {
166
                application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken);
167

168
                if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
169
                {
170
                    application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken);
171
                    application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeToken);
172
                }
173
            }
174

175
            if (!redirectUri.IsNullOrWhiteSpace() || !postLogoutRedirectUri.IsNullOrWhiteSpace())
176
            {
177
                application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Logout);
178
            }
179

180
            var buildInGrantTypes = new []
181
            {
182
                OpenIddictConstants.GrantTypes.Implicit,
183
                OpenIddictConstants.GrantTypes.Password,
184
                OpenIddictConstants.GrantTypes.AuthorizationCode,
185
                OpenIddictConstants.GrantTypes.ClientCredentials,
186
                OpenIddictConstants.GrantTypes.DeviceCode,
187
                OpenIddictConstants.GrantTypes.RefreshToken
188
            };
189

190
            foreach (var grantType in grantTypes)
191
            {
192
              if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode)
193
              {
194
                  application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode);
195
                  application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Code);
196
              }
197

198
              if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || grantType == OpenIddictConstants.GrantTypes.Implicit)
199
              {
200
                  application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization);
201
              }
202

203
              if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode ||
204
                  grantType == OpenIddictConstants.GrantTypes.ClientCredentials ||
205
                  grantType == OpenIddictConstants.GrantTypes.Password ||
206
                  grantType == OpenIddictConstants.GrantTypes.RefreshToken ||
207
                  grantType == OpenIddictConstants.GrantTypes.DeviceCode)
208
              {
209
                  application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token);
210
                  application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Revocation);
211
                  application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Introspection);
212
              }
213

214
              if (grantType == OpenIddictConstants.GrantTypes.ClientCredentials)
215
              {
216
                  application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials);
217
              }
218

219
              if (grantType == OpenIddictConstants.GrantTypes.Implicit)
220
              {
221
                  application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit);
222
              }
223

224
              if (grantType == OpenIddictConstants.GrantTypes.Password)
225
              {
226
                  application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password);
227
              }
228

229
              if (grantType == OpenIddictConstants.GrantTypes.RefreshToken)
230
              {
231
                  application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken);
232
              }
233

234
              if (grantType == OpenIddictConstants.GrantTypes.DeviceCode)
235
              {
236
                  application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.DeviceCode);
237
                  application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Device);
238
              }
239

240
              if (grantType == OpenIddictConstants.GrantTypes.Implicit)
241
              {
242
                  application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdToken);
243
                  if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
244
                  {
245
                      application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken);
246
                      application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Token);
247
                  }
248
              }
249

250
              if (!buildInGrantTypes.Contains(grantType))
251
              {
252
                  application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.GrantType + grantType);
253
              }
254
            }
255

256
            var buildInScopes = new []
257
            {
258
                OpenIddictConstants.Permissions.Scopes.Address,
259
                OpenIddictConstants.Permissions.Scopes.Email,
260
                OpenIddictConstants.Permissions.Scopes.Phone,
261
                OpenIddictConstants.Permissions.Scopes.Profile,
262
                OpenIddictConstants.Permissions.Scopes.Roles
263
            };
264

265
            foreach (var scope in scopes)
266
            {
267
                if (buildInScopes.Contains(scope))
268
                {
269
                    application.Permissions.Add(scope);
270
                }
271
                else
272
                {
273
                    application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.Scope + scope);
274
                }
275
            }
276

277
            if (redirectUri != null)
278
            {
279
                if (!redirectUri.IsNullOrEmpty())
280
                {
281
                    if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString())
282
                    {
283
                        throw new BusinessException(L["InvalidRedirectUri", redirectUri]);
284
                    }
285

286
                    if (application.RedirectUris.All(x => x != uri))
287
                    {
288
                        application.RedirectUris.Add(uri);
289
                    }
290
                }
291
            }
292

293
            if (postLogoutRedirectUri != null)
294
            {
295
                if (!postLogoutRedirectUri.IsNullOrEmpty())
296
                {
297
                    if (!Uri.TryCreate(postLogoutRedirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString())
298
                    {
299
                        throw new BusinessException(L["InvalidPostLogoutRedirectUri", postLogoutRedirectUri]);
300
                    }
301

302
                    if (application.PostLogoutRedirectUris.All(x => x != uri))
303
                    {
304
                        application.PostLogoutRedirectUris.Add(uri);
305
                    }
306
                }
307
            }
308

309
            if (permissions != null)
310
            {
311
                await _permissionDataSeeder.SeedAsync(
312
                    ClientPermissionValueProvider.ProviderName,
313
                    name,
314
                    permissions,
315
                    null
316
                );
317
            }
318

319
            await _applicationManager.CreateAsync(application);
320
        }
321
    }
322
}
323

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.