Browse Source

Merge pull request #23281 from abpframework/OpenIddict-7.0

Update `OpenIddict` to 7.0.0.
pull/23315/head
Engincan VESKE 1 year ago
committed by GitHub
parent
commit
c0402ac030
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      Directory.Packages.props
  2. 35
      modules/openiddict/app/OpenIddict.Demo.Client.Console/Program.cs
  3. 1
      modules/openiddict/app/OpenIddict.Demo.Server/EntityFrameworkCore/ServerDataSeedContributor.cs
  4. 6
      modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250710090114_Initial.Designer.cs
  5. 2
      modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250710090114_Initial.cs
  6. 4
      modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs
  7. 3
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs
  8. 2
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs
  9. 92
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.TokenExchange.cs
  10. 5
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.cs
  11. 2
      modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Tokens/OpenIddictTokenConsts.cs
  12. 19
      modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/AbpOpenIddictDomainModule.cs
  13. 2
      modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationManager.cs
  14. 2
      modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Authorizations/AbpAuthorizationManager.cs
  15. 2
      modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Scopes/AbpScopeManager.cs
  16. 2
      modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Tokens/AbpTokenManager.cs

10
Directory.Packages.props

@ -128,11 +128,11 @@
<PackageVersion Include="NUglify" Version="1.21.15" />
<PackageVersion Include="Nullable" Version="1.3.1" />
<PackageVersion Include="Octokit" Version="14.0.0" />
<PackageVersion Include="OpenIddict.Abstractions" Version="6.4.0" />
<PackageVersion Include="OpenIddict.Core" Version="6.4.0" />
<PackageVersion Include="OpenIddict.Server.AspNetCore" Version="6.4.0" />
<PackageVersion Include="OpenIddict.Validation.AspNetCore" Version="6.4.0" />
<PackageVersion Include="OpenIddict.Validation.ServerIntegration" Version="6.4.0" />
<PackageVersion Include="OpenIddict.Abstractions" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Core" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Server.AspNetCore" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Validation.AspNetCore" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Validation.ServerIntegration" Version="7.0.0" />
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.80" />
<PackageVersion Include="Polly" Version="8.5.2" />
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0" />

35
modules/openiddict/app/OpenIddict.Demo.Client.Console/Program.cs

@ -75,6 +75,41 @@ Console.WriteLine("UserInfo: {0}", JsonSerializer.Serialize(JsonDocument.Parse(u
}));
Console.WriteLine();
var tokenExchangeResponse = await client.RequestTokenExchangeTokenAsync(new TokenExchangeTokenRequest()
{
Address = configuration.TokenEndpoint,
ClientId = clientId,
ClientSecret = clientSecret,
SubjectToken = refreshTokenResponse.AccessToken!,
SubjectTokenType = "urn:ietf:params:oauth:token-type:access_token",
Scope = "AbpAPI profile roles email phone offline_access",
});
if (tokenExchangeResponse.IsError)
{
throw new Exception(tokenExchangeResponse.Error);
}
Console.WriteLine("Token Exchange token: {0}", tokenExchangeResponse.AccessToken);
Console.WriteLine();
Console.WriteLine("Token Exchange token: {0}", tokenExchangeResponse.RefreshToken);
Console.WriteLine();
userinfo = await client.GetUserInfoAsync(new UserInfoRequest()
{
Address = configuration.UserInfoEndpoint,
Token = tokenExchangeResponse.AccessToken
});
if (userinfo.IsError)
{
throw new Exception(userinfo.Error);
}
Console.WriteLine("Token Exchange UserInfo: {0}", JsonSerializer.Serialize(JsonDocument.Parse(userinfo.Raw), new JsonSerializerOptions
{
WriteIndented = true
}));
Console.WriteLine();
var introspectionResponse = await client.IntrospectTokenAsync(new TokenIntrospectionRequest()
{

1
modules/openiddict/app/OpenIddict.Demo.Server/EntityFrameworkCore/ServerDataSeedContributor.cs

@ -79,6 +79,7 @@ public class ServerDataSeedContributor : IDataSeedContributor, ITransientDepende
OpenIddictConstants.Permissions.GrantTypes.RefreshToken,
OpenIddictConstants.Permissions.GrantTypes.DeviceCode,
OpenIddictConstants.Permissions.GrantTypes.ClientCredentials,
OpenIddictConstants.Permissions.GrantTypes.TokenExchange,
OpenIddictConstants.Permissions.Prefixes.GrantType + MyTokenExtensionGrant.ExtensionGrantName,
OpenIddictConstants.Permissions.ResponseTypes.Code,

6
modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250630055813_Initial.Designer.cs → modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250710090114_Initial.Designer.cs

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace OpenIddict.Demo.Server.Migrations
{
[DbContext(typeof(ServerDbContext))]
[Migration("20250630055813_Initial")]
[Migration("20250710090114_Initial")]
partial class Initial
{
/// <inheritdoc />
@ -1164,8 +1164,8 @@ namespace OpenIddict.Demo.Server.Migrations
.HasColumnType("nvarchar(400)");
b.Property<string>("Type")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasMaxLength(150)
.HasColumnType("nvarchar(150)");
b.HasKey("Id");

2
modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250630055813_Initial.cs → modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250710090114_Initial.cs

@ -645,7 +645,7 @@ namespace OpenIddict.Demo.Server.Migrations
ReferenceId = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
Status = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
Subject = table.Column<string>(type: "nvarchar(400)", maxLength: 400, nullable: true),
Type = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
Type = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: true),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false)
},

4
modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs

@ -1161,8 +1161,8 @@ namespace OpenIddict.Demo.Server.Migrations
.HasColumnType("nvarchar(400)");
b.Property<string>("Type")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasMaxLength(150)
.HasColumnType("nvarchar(150)");
b.HasKey("Id");

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

@ -79,7 +79,8 @@ public class AbpOpenIddictAspNetCoreModule : AbpModule
.AllowClientCredentialsFlow()
.AllowRefreshTokenFlow()
.AllowDeviceAuthorizationFlow()
.AllowNoneFlow();
.AllowNoneFlow()
.AllowTokenExchangeFlow();
builder.RegisterScopes(new[]
{

2
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs

@ -44,7 +44,7 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
if (result is not { Succeeded: true } ||
((request.HasPromptValue(OpenIddictConstants.PromptValues.Login) || request.MaxAge is 0 ||
(request.MaxAge != null && result.Properties?.IssuedUtc != null &&
(request.MaxAge is not null && result.Properties?.IssuedUtc is not null &&
TimeProvider.System.GetUtcNow() - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value))) &&
TempData["IgnoreAuthenticationChallenge"] is null or false))
{

92
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.TokenExchange.cs

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions;
using OpenIddict.Server.AspNetCore;
namespace Volo.Abp.OpenIddict.Controllers;
public partial class TokenController
{
protected virtual async Task<IActionResult> HandleTokenExchangeGrantTypeAsync(OpenIddictRequest request)
{
// Retrieve the claims principal stored in the subject token.
//
// Note: the principal may not represent a user (e.g if the token was issued during a client credentials token
// request and represents a client application): developers are strongly encouraged to ensure that the user
// and client identifiers are randomly generated so that a malicious client cannot impersonate a legit user.
//
// See https://datatracker.ietf.org/doc/html/rfc9068#SecurityConsiderations for more information.
var result = await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
// If available, retrieve the claims principal stored in the actor token.
var actor = result.Properties?.GetParameter<ClaimsPrincipal>(OpenIddictServerAspNetCoreConstants.Properties.ActorTokenPrincipal);
// Retrieve the user profile corresponding to the subject token.
var user = await UserManager.FindByIdAsync(result.Principal!.GetClaim(OpenIddictConstants.Claims.Subject)!);
if (user is null)
{
return Forbid(
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The token is no longer valid."
}));
}
// Ensure the user is still allowed to sign in.
if (!await PreSignInCheckAsync(user))
{
return Forbid(
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties(new Dictionary<string, string?>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is no longer allowed to sign in."
}));
}
// Note: whether the identity represents a delegated or impersonated access (or any other
// model) is entirely up to the implementer: to support all scenarios, OpenIddict doesn't
// enforce any specific constraint on the identity used for the sign-in operation and only
// requires that the standard "act" and "may_act" claims be valid JSON objects if present.
// Clear the dynamic claims cache.
await IdentityDynamicClaimsPrincipalContributorCache.ClearAsync(user.Id, user.TenantId);
// Create a new ClaimsPrincipal containing the claims that
// will be used to create an id_token, a token or a code.
var principal = await SignInManager.CreateUserPrincipalAsync(user);
// Note: IdentityModel doesn't support serializing ClaimsIdentity.Actor to the
// standard "act" claim yet, which requires adding the "act" claim manually.
//
// For more information, see
// https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/3219.
if (!string.IsNullOrEmpty(actor?.GetClaim(OpenIddictConstants.Claims.Subject)) &&
!string.Equals(principal.GetClaim(OpenIddictConstants.Claims.Subject), actor.GetClaim(OpenIddictConstants.Claims.Subject), StringComparison.Ordinal))
{
principal.SetClaim(OpenIddictConstants.Claims.Actor, new JsonObject
{
[OpenIddictConstants.Claims.Subject] = actor.GetClaim(OpenIddictConstants.Claims.Subject)
});
}
// Note: in this sample, the granted scopes match the requested scope
// but you may want to allow the user to uncheck specific scopes.
// For that, simply restrict the list of scopes before calling SetScopes.
principal.SetScopes(request.GetScopes());
principal.SetResources(await GetResourcesAsync(request.GetScopes()));
await OpenIddictClaimsPrincipalManager.HandleAsync(request, principal);
// Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
}
}

5
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.cs

@ -42,6 +42,11 @@ public partial class TokenController : AbpOpenIdDictControllerBase
return await HandleClientCredentialsAsync(request);
}
if (request.IsTokenExchangeGrantType())
{
return await HandleTokenExchangeGrantTypeAsync(request);
}
var extensionGrantsOptions = HttpContext.RequestServices.GetRequiredService<IOptions<AbpOpenIddictExtensionGrantsOptions>>();
var extensionTokenGrant = extensionGrantsOptions.Value.Find<ITokenExtensionGrant>(request.GrantType);
if (extensionTokenGrant != null)

2
modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Tokens/OpenIddictTokenConsts.cs

@ -8,5 +8,5 @@ public class OpenIddictTokenConsts
public static int SubjectMaxLength { get; set; } = 400;
public static int TypeMaxLength { get; set; } = 50;
public static int TypeMaxLength { get; set; } = 150;
}

19
modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/AbpOpenIddictDomainModule.cs

@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Caching;
using Volo.Abp.DistributedLocking;
@ -65,15 +66,15 @@ public class AbpOpenIddictDomainModule : AbpModule
.SetDefaultTokenEntity<OpenIddictTokenModel>();
builder
.AddApplicationStore<AbpOpenIddictApplicationStore>()
.AddAuthorizationStore<AbpOpenIddictAuthorizationStore>()
.AddScopeStore<AbpOpenIddictScopeStore>()
.AddTokenStore<AbpOpenIddictTokenStore>();
builder.ReplaceApplicationManager(typeof(AbpApplicationManager));
builder.ReplaceAuthorizationManager(typeof(AbpAuthorizationManager));
builder.ReplaceScopeManager(typeof(AbpScopeManager));
builder.ReplaceTokenManager(typeof(AbpTokenManager));
.ReplaceApplicationStore<OpenIddictApplicationModel, AbpOpenIddictApplicationStore>()
.ReplaceAuthorizationStore<OpenIddictAuthorizationModel, AbpOpenIddictAuthorizationStore>()
.ReplaceScopeStore<OpenIddictScopeModel, AbpOpenIddictScopeStore>()
.ReplaceTokenStore<OpenIddictTokenModel, AbpOpenIddictTokenStore>();
builder.ReplaceApplicationManager<OpenIddictApplicationModel, AbpApplicationManager>();
builder.ReplaceAuthorizationManager<OpenIddictAuthorizationModel, AbpAuthorizationManager>();
builder.ReplaceScopeManager<OpenIddictScopeModel, AbpScopeManager>();
builder.ReplaceTokenManager<OpenIddictTokenModel, AbpTokenManager>();
builder.Services.TryAddScoped(provider => (IAbpApplicationManager)provider.GetRequiredService<IOpenIddictApplicationManager>());

2
modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationManager.cs

@ -17,7 +17,7 @@ public class AbpApplicationManager : OpenIddictApplicationManager<OpenIddictAppl
[NotNull] IOpenIddictApplicationCache<OpenIddictApplicationModel> cache,
[NotNull] ILogger<AbpApplicationManager> logger,
[NotNull] IOptionsMonitor<OpenIddictCoreOptions> options,
[NotNull] IOpenIddictApplicationStoreResolver resolver,
[NotNull] IOpenIddictApplicationStore<OpenIddictApplicationModel> resolver,
AbpOpenIddictIdentifierConverter identifierConverter)
: base(cache, logger, options, resolver)
{

2
modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Authorizations/AbpAuthorizationManager.cs

@ -16,7 +16,7 @@ public class AbpAuthorizationManager : OpenIddictAuthorizationManager<OpenIddict
[NotNull] [ItemNotNull] IOpenIddictAuthorizationCache<OpenIddictAuthorizationModel> cache,
[NotNull] [ItemNotNull] ILogger<OpenIddictAuthorizationManager<OpenIddictAuthorizationModel>> logger,
[NotNull] [ItemNotNull] IOptionsMonitor<OpenIddictCoreOptions> options,
[NotNull] IOpenIddictAuthorizationStoreResolver resolver,
[NotNull] IOpenIddictAuthorizationStore<OpenIddictAuthorizationModel> resolver,
AbpOpenIddictIdentifierConverter identifierConverter)
: base(cache, logger, options, resolver)
{

2
modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Scopes/AbpScopeManager.cs

@ -16,7 +16,7 @@ public class AbpScopeManager : OpenIddictScopeManager<OpenIddictScopeModel>
[NotNull] [ItemNotNull] IOpenIddictScopeCache<OpenIddictScopeModel> cache,
[NotNull] [ItemNotNull] ILogger<OpenIddictScopeManager<OpenIddictScopeModel>> logger,
[NotNull] [ItemNotNull] IOptionsMonitor<OpenIddictCoreOptions> options,
[NotNull] IOpenIddictScopeStoreResolver resolver,
[NotNull] IOpenIddictScopeStore<OpenIddictScopeModel> resolver,
AbpOpenIddictIdentifierConverter identifierConverter)
: base(cache, logger, options, resolver)
{

2
modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Tokens/AbpTokenManager.cs

@ -16,7 +16,7 @@ public class AbpTokenManager : OpenIddictTokenManager<OpenIddictTokenModel>
[NotNull] [ItemNotNull] IOpenIddictTokenCache<OpenIddictTokenModel> cache,
[NotNull] [ItemNotNull] ILogger<OpenIddictTokenManager<OpenIddictTokenModel>> logger,
[NotNull] [ItemNotNull] IOptionsMonitor<OpenIddictCoreOptions> options,
[NotNull] IOpenIddictTokenStoreResolver resolver,
[NotNull] IOpenIddictTokenStore<OpenIddictTokenModel> resolver,
AbpOpenIddictIdentifierConverter identifierConverter)
: base(cache, logger, options, resolver)
{

Loading…
Cancel
Save