Browse Source

Merge branch 'dev' into auto-merge/rel-10-4/4549

pull/25384/head
selman koc 2 weeks ago
committed by GitHub
parent
commit
30178d0c20
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 24
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  2. 4
      common.props
  3. 12
      docs/en/modules/openiddict.md
  4. 4
      modules/openiddict/app/OpenIddict.Demo.Server/OpenIddict.Demo.Server.csproj
  5. 7
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs
  6. 29
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictOptions.cs
  7. 92
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultScopesHandler.cs

24
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -348,15 +348,39 @@
"CompanySize": "Company size",
"DetailTrialLicense": "Details",
"Requested": "Requested",
"Pending": "Pending",
"Running": "Running",
"Activated": "Activated",
"PurchasedToNormalLicense": "Purchased",
"Expired": "Expired",
"TrialLicenseDeletionWarningMessage": "Are you sure you want to delete the trial license? Trial license, organization, support accounts will be deleted!",
"LicenseCategoryFilter": "License category",
"Permission:SendWelcomeEmail": "Send Welcome Email",
"Permission:ProvisionExistingOrganizationsAi": "Provision Existing Organizations AI",
"SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmailWarningMessage": "Are you sure you want to send welcome email to the organization members?",
"SendWelcomeEmailSuccessMessage": "Welcome email sent successfully!",
"ProvisionExistingOrganizationsAi": "Provision Existing Organizations AI",
"ProvisionExistingOrganizationsAiConfirmation": "This will enable AI assisted development for all active organizations, grant included AI credits, and provision provider keys in the background. Do you want to continue?",
"DeleteExistingOrganizationsAiCredentials": "Delete Existing Organizations AI Keys",
"DeleteExistingOrganizationsAiCredentialsConfirmation": "This will revoke existing OpenRouter keys referenced by organizations and remove stored AI credentials from the database so provisioning can be retried. Do you want to continue?",
"ExistingOrganizationsAiOperationAlreadyRunning": "Another existing organizations AI operation is already running.",
"ExistingOrganizationsAiBackfillAlreadyRunning": "An existing organizations AI provisioning job is already running.",
"ExistingOrganizationsAiBackfillMissingManagementApiKey": "OpenRouter management API key is not configured for the admin application. Configure AiAssistedDevelopment:Providers:OpenRouter:ManagementApiKey before starting this operation.",
"NoActiveOrganizationsFoundForAiBackfill": "No active organizations were found for AI provisioning.",
"NoOrganizationsFoundForAiCredentialCleanup": "No organizations with AI credentials were found for cleanup.",
"ExistingOrganizationsAiBackfillNotFound": "The existing organizations AI provisioning operation was not found.",
"ExistingOrganizationsAiBackfillCompleted": "Existing organizations AI provisioning completed successfully.",
"ExistingOrganizationsAiBackfillFailed": "Existing organizations AI provisioning failed.",
"ExistingOrganizationsAiCredentialCleanupCompleted": "Existing organizations AI credential cleanup completed successfully.",
"ExistingOrganizationsAiCredentialCleanupFailed": "Existing organizations AI credential cleanup failed.",
"CurrentOrganization": "Current organization",
"Processed": "Processed",
"Succeeded": "Succeeded",
"Failed": "Failed",
"Cancelled": "Cancelled",
"CompletedAt": "Completed at",
"LastError": "Last error",
"Activate": "Activate",
"ActivateTrialLicenseWarningMessage": " When you activate a trial license, a welcome e-mail will be sent to the user. Do you want to activate it?",
"ActivateTrialLicenseSuccessMessage": "Activated successfully and the welcome e-mail sent to the organization members.",

4
common.props

@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>10.4.0-rc.2</Version>
<LeptonXVersion>5.4.0-rc.2</LeptonXVersion>
<Version>10.5.0-preview</Version>
<LeptonXVersion>5.5.0-preview</LeptonXVersion>
<NoWarn>$(NoWarn);CS1591;CS0436</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io/</PackageProjectUrl>

12
docs/en/modules/openiddict.md

@ -303,6 +303,18 @@ PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
- `UpdateAbpClaimTypes(default: true)`: Updates `AbpClaimTypes` to be compatible with the Openiddict claims.
- `AddDevelopmentEncryptionAndSigningCertificate(default: true)`: Registers (and generates if necessary) a user-specific development encryption/development signing certificate. This is a certificate used for signing and encrypting the tokens and for **development environment only**. You must set it to **false** for non-development environments.
- `UseDefaultScopesForClientCredentials(default: false)`: When set to `true`, the access token issued for the `client_credentials` grant automatically grants the scopes configured on the client application (permissions prefixed with `oi_scp:`) when the client does not explicitly request any scope.
- `UseDefaultScopesForPassword(default: false)`: When set to `true`, the token response for the `password` grant automatically grants the scopes configured on the client application when the client does not explicitly request any scope. If the configured scopes include `openid`/`profile`/`email`/`roles`, the corresponding `id_token` and claim destinations are affected as well.
- `UseDefaultScopesForTokenExchange(default: false)`: When set to `true`, the token response for the `urn:ietf:params:oauth:grant-type:token-exchange` grant automatically grants the scopes configured on the client application when the client does not explicitly request any scope. If the configured scopes include `openid`/`profile`/`email`/`roles`, the corresponding `id_token` and claim destinations are affected as well.
Example to enable the default-scope fallback for the `client_credentials` grant:
```csharp
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
options.UseDefaultScopesForClientCredentials = true;
});
```
> `AddDevelopmentEncryptionAndSigningCertificate` cannot be used in applications deployed on IIS or Azure App Service: trying to use them on IIS or Azure App Service will result in an exception being thrown at runtime (unless the application pool is configured to load a user profile). To avoid that, consider creating self-signed certificates and storing them in the X.509 certificates store of the host machine(s). Please refer to: https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html#registering-a-development-certificate

4
modules/openiddict/app/OpenIddict.Demo.Server/OpenIddict.Demo.Server.csproj

@ -68,6 +68,10 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>compile; contentFiles; build; buildMultitargeting; buildTransitive; analyzers; native</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>compile; contentFiles; build; buildMultitargeting; buildTransitive; analyzers; native</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>

7
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs

@ -25,9 +25,16 @@ public class AbpOpenIddictAspNetCoreModule : AbpModule
Configure<AbpOpenIddictClaimsPrincipalOptions>(options =>
{
options.ClaimsPrincipalHandlers.Add<AbpDefaultScopesHandler>();
options.ClaimsPrincipalHandlers.Add<AbpDefaultOpenIddictClaimsPrincipalHandler>();
});
var preActions = context.Services.GetPreConfigureActions<AbpOpenIddictAspNetCoreOptions>();
Configure<AbpOpenIddictAspNetCoreOptions>(options =>
{
preActions.Configure(options);
});
Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationFormats.Add("/Volo/Abp/OpenIddict/Views/{1}/{0}.cshtml");

29
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictOptions.cs

@ -25,4 +25,33 @@ public class AbpOpenIddictAspNetCoreOptions
/// Set the url of the select account page.
/// </summary>
public string SelectAccountPage { get; set; } = "~/Account/SelectAccount";
/// <summary>
/// When set to <c>true</c>, the access token issued for the <c>client_credentials</c> grant
/// automatically includes the scopes configured on the client application (permissions
/// prefixed with <c>oi_scp:</c>) when the client does not explicitly request any scope.
/// Default: false.
/// </summary>
public bool UseDefaultScopesForClientCredentials { get; set; }
/// <summary>
/// When set to <c>true</c>, the token response for the <c>password</c> grant automatically
/// grants the scopes configured on the client application (permissions prefixed with
/// <c>oi_scp:</c>) when the client does not explicitly request any scope. If the configured
/// scopes include <c>openid</c>/<c>profile</c>/<c>email</c>/<c>roles</c>, the corresponding
/// id_token and claim destinations are affected as well.
/// Default: false.
/// </summary>
public bool UseDefaultScopesForPassword { get; set; }
/// <summary>
/// When set to <c>true</c>, the token response for the
/// <c>urn:ietf:params:oauth:grant-type:token-exchange</c> grant automatically grants the
/// scopes configured on the client application (permissions prefixed with <c>oi_scp:</c>)
/// when the client does not explicitly request any scope. If the configured scopes include
/// <c>openid</c>/<c>profile</c>/<c>email</c>/<c>roles</c>, the corresponding id_token and
/// claim destinations are affected as well.
/// Default: false.
/// </summary>
public bool UseDefaultScopesForTokenExchange { get; set; }
}

92
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultScopesHandler.cs

@ -0,0 +1,92 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.OpenIddict;
public class AbpDefaultScopesHandler : IAbpOpenIddictClaimsPrincipalHandler, ITransientDependency
{
public ILogger<AbpDefaultScopesHandler> Logger { get; set; }
= NullLogger<AbpDefaultScopesHandler>.Instance;
public virtual async Task HandleAsync(AbpOpenIddictClaimsPrincipalHandlerContext context)
{
var options = context.ScopeServiceProvider
.GetRequiredService<IOptions<AbpOpenIddictAspNetCoreOptions>>().Value;
var request = context.OpenIddictRequest;
if (!IsDefaultScopesEnabled(request, options))
{
return;
}
if (!context.Principal.GetScopes().IsDefaultOrEmpty)
{
return;
}
var clientId = request.ClientId;
if (string.IsNullOrEmpty(clientId))
{
return;
}
var applicationManager = context.ScopeServiceProvider.GetRequiredService<IOpenIddictApplicationManager>();
var scopeManager = context.ScopeServiceProvider.GetRequiredService<IOpenIddictScopeManager>();
var application = await applicationManager.FindByClientIdAsync(clientId);
if (application == null)
{
return;
}
var permissions = await applicationManager.GetPermissionsAsync(application);
var prefix = OpenIddictConstants.Permissions.Prefixes.Scope;
var scopes = permissions
.Where(p => p.StartsWith(prefix, StringComparison.Ordinal))
.Select(p => p[prefix.Length..])
.ToImmutableArray();
if (scopes.IsDefaultOrEmpty)
{
return;
}
Logger.LogDebug(
"Injecting default scopes for client {ClientId} (grant_type {GrantType}): {Scopes}",
clientId,
request.GrantType,
string.Join(", ", scopes));
context.Principal.SetScopes(scopes);
context.Principal.SetResources(await scopeManager.ListResourcesAsync(scopes).ToListAsync());
}
protected virtual bool IsDefaultScopesEnabled(OpenIddictRequest request, AbpOpenIddictAspNetCoreOptions options)
{
if (request.IsClientCredentialsGrantType())
{
return options.UseDefaultScopesForClientCredentials;
}
if (request.IsPasswordGrantType())
{
return options.UseDefaultScopesForPassword;
}
if (request.IsTokenExchangeGrantType())
{
return options.UseDefaultScopesForTokenExchange;
}
return false;
}
}
Loading…
Cancel
Save