From a25907cd523d01f542255c7e11305e6ae3955af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Fri, 27 Dec 2019 19:01:36 +0100 Subject: [PATCH] Automatically map the scope/azp access token claims to their OpenIddict private claims equivalents --- .../Controllers/UserinfoController.cs | 28 ++--- .../OpenIddictConstants.cs | 12 +- .../Primitives/OpenIddictExtensions.cs | 28 ++--- .../Managers/OpenIddictApplicationManager.cs | 24 ++-- .../OpenIddictAuthorizationManager.cs | 15 +-- .../Managers/OpenIddictScopeManager.cs | 3 +- .../Managers/OpenIddictTokenManager.cs | 29 ++--- ...OpenIddictServerDataProtectionConstants.cs | 2 - ...OpenIddictServerDataProtectionFormatter.cs | 3 + .../OpenIddictServerDataProtectionHandlers.cs | 32 ++--- .../OpenIddictServerHandlers.Introspection.cs | 2 +- .../OpenIddictServerHandlers.cs | 69 ++++++----- ...IddictValidationDataProtectionConstants.cs | 2 - ...IddictValidationDataProtectionFormatter.cs | 3 +- ...nIddictValidationDataProtectionHandlers.cs | 2 +- .../OpenIddictValidationHandlers.cs | 16 ++- .../Primitives/OpenIddictExtensionsTests.cs | 112 +++++++++--------- ...enIddictServerIntegrationTests.Exchange.cs | 64 +++++----- .../OpenIddictServerIntegrationTests.cs | 6 +- 19 files changed, 233 insertions(+), 219 deletions(-) diff --git a/samples/Mvc.Server/Controllers/UserinfoController.cs b/samples/Mvc.Server/Controllers/UserinfoController.cs index acdbe83b..0748ceb7 100644 --- a/samples/Mvc.Server/Controllers/UserinfoController.cs +++ b/samples/Mvc.Server/Controllers/UserinfoController.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc; using Mvc.Server.Models; using OpenIddict.Abstractions; using OpenIddict.Server.AspNetCore; +using static OpenIddict.Abstractions.OpenIddictConstants; namespace Mvc.Server.Controllers { @@ -15,9 +16,7 @@ namespace Mvc.Server.Controllers private readonly UserManager _userManager; public UserinfoController(UserManager userManager) - { - _userManager = userManager; - } + => _userManager = userManager; // // GET: /api/userinfo @@ -31,24 +30,25 @@ namespace Mvc.Server.Controllers return Challenge(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); } - var claims = new Dictionary(StringComparer.Ordinal); - - // Note: the "sub" claim is a mandatory claim and must be included in the JSON response. - claims[OpenIddictConstants.Claims.Subject] = await _userManager.GetUserIdAsync(user); + var claims = new Dictionary(StringComparer.Ordinal) + { + // Note: the "sub" claim is a mandatory claim and must be included in the JSON response. + [Claims.Subject] = await _userManager.GetUserIdAsync(user) + }; - if (User.HasClaim(OpenIddictConstants.Claims.Scope, OpenIddictConstants.Scopes.Email)) + if (User.HasScope(Scopes.Email)) { - claims[OpenIddictConstants.Claims.Email] = await _userManager.GetEmailAsync(user); - claims[OpenIddictConstants.Claims.EmailVerified] = await _userManager.IsEmailConfirmedAsync(user); + claims[Claims.Email] = await _userManager.GetEmailAsync(user); + claims[Claims.EmailVerified] = await _userManager.IsEmailConfirmedAsync(user); } - if (User.HasClaim(OpenIddictConstants.Claims.Scope, OpenIddictConstants.Scopes.Phone)) + if (User.HasScope(Scopes.Phone)) { - claims[OpenIddictConstants.Claims.PhoneNumber] = await _userManager.GetPhoneNumberAsync(user); - claims[OpenIddictConstants.Claims.PhoneNumberVerified] = await _userManager.IsPhoneNumberConfirmedAsync(user); + claims[Claims.PhoneNumber] = await _userManager.GetPhoneNumberAsync(user); + claims[Claims.PhoneNumberVerified] = await _userManager.IsPhoneNumberConfirmedAsync(user); } - if (User.HasClaim(OpenIddictConstants.Claims.Scope, "roles")) + if (User.HasScope("roles")) { claims["roles"] = await _userManager.GetRolesAsync(user); } diff --git a/src/OpenIddict.Abstractions/OpenIddictConstants.cs b/src/OpenIddict.Abstractions/OpenIddictConstants.cs index 2331e716..3a2ec4d2 100644 --- a/src/OpenIddict.Abstractions/OpenIddictConstants.cs +++ b/src/OpenIddict.Abstractions/OpenIddictConstants.cs @@ -103,7 +103,7 @@ namespace OpenIddict.Abstractions public const string Resources = "oi_rsrc"; public const string Scopes = "oi_scp"; public const string TokenId = "oi_tkn_id"; - public const string TokenUsage = "oi_tkn_use"; + public const string TokenType = "oi_tkn_typ"; public const string UserCodeLifetime = "oi_usrc_lft"; } } @@ -428,15 +428,5 @@ namespace OpenIddict.Abstractions { public const string Bearer = "Bearer"; } - - public static class TokenUsages - { - public const string AccessToken = "access_token"; - public const string AuthorizationCode = "authorization_code"; - public const string DeviceCode = "device_code"; - public const string IdToken = "id_token"; - public const string RefreshToken = "refresh_token"; - public const string UserCode = "user_code"; - } } } diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs index 12754f90..327c05f8 100644 --- a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs +++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs @@ -1359,12 +1359,12 @@ namespace OpenIddict.Abstractions => principal.GetClaim(Claims.Private.TokenId); /// - /// Gets the token usage associated with the claims principal. + /// Gets the token type associated with the claims principal. /// /// The claims principal. - /// The token usage or null if the claim cannot be found. - public static string GetTokenUsage([NotNull] this ClaimsPrincipal principal) - => principal.GetClaim(Claims.Private.TokenUsage); + /// The token type or null if the claim cannot be found. + public static string GetTokenType([NotNull] this ClaimsPrincipal principal) + => principal.GetClaim(Claims.Private.TokenType); /// /// Gets a boolean value indicating whether the claims principal corresponds to an access token. @@ -1378,7 +1378,7 @@ namespace OpenIddict.Abstractions throw new ArgumentNullException(nameof(principal)); } - return string.Equals(principal.GetTokenUsage(), TokenUsages.AccessToken, StringComparison.OrdinalIgnoreCase); + return string.Equals(principal.GetTokenType(), TokenTypeHints.AccessToken, StringComparison.OrdinalIgnoreCase); } /// @@ -1393,7 +1393,7 @@ namespace OpenIddict.Abstractions throw new ArgumentNullException(nameof(principal)); } - return string.Equals(principal.GetTokenUsage(), TokenUsages.AuthorizationCode, StringComparison.OrdinalIgnoreCase); + return string.Equals(principal.GetTokenType(), TokenTypeHints.AuthorizationCode, StringComparison.OrdinalIgnoreCase); } /// @@ -1408,7 +1408,7 @@ namespace OpenIddict.Abstractions throw new ArgumentNullException(nameof(principal)); } - return string.Equals(principal.GetTokenUsage(), TokenUsages.DeviceCode, StringComparison.OrdinalIgnoreCase); + return string.Equals(principal.GetTokenType(), TokenTypeHints.DeviceCode, StringComparison.OrdinalIgnoreCase); } /// @@ -1423,7 +1423,7 @@ namespace OpenIddict.Abstractions throw new ArgumentNullException(nameof(principal)); } - return string.Equals(principal.GetTokenUsage(), TokenUsages.IdToken, StringComparison.OrdinalIgnoreCase); + return string.Equals(principal.GetTokenType(), TokenTypeHints.IdToken, StringComparison.OrdinalIgnoreCase); } /// @@ -1438,7 +1438,7 @@ namespace OpenIddict.Abstractions throw new ArgumentNullException(nameof(principal)); } - return string.Equals(principal.GetTokenUsage(), TokenUsages.RefreshToken, StringComparison.OrdinalIgnoreCase); + return string.Equals(principal.GetTokenType(), TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase); } /// @@ -1453,7 +1453,7 @@ namespace OpenIddict.Abstractions throw new ArgumentNullException(nameof(principal)); } - return string.Equals(principal.GetTokenUsage(), TokenUsages.UserCode, StringComparison.OrdinalIgnoreCase); + return string.Equals(principal.GetTokenType(), TokenTypeHints.UserCode, StringComparison.OrdinalIgnoreCase); } /// @@ -1887,13 +1887,13 @@ namespace OpenIddict.Abstractions => principal.SetClaim(Claims.Private.TokenId, identifier); /// - /// Sets the token usage associated with the claims principal. + /// Sets the token type associated with the claims principal. /// /// The claims principal. - /// The token usage to store. + /// The token type to store. /// The claims principal. - public static ClaimsPrincipal SetTokenUsage([NotNull] this ClaimsPrincipal principal, string usage) - => principal.SetClaim(Claims.Private.TokenUsage, usage); + public static ClaimsPrincipal SetTokenType([NotNull] this ClaimsPrincipal principal, string type) + => principal.SetClaim(Claims.Private.TokenType, type); private static IEnumerable GetValues(string source, char[] separators) { diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs index 88542692..eeda48f1 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -18,6 +18,7 @@ using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; +using static OpenIddict.Abstractions.OpenIddictConstants; #if !SUPPORTS_KEY_DERIVATION_WITH_SPECIFIED_HASH_ALGORITHM using Org.BouncyCastle.Crypto; @@ -139,8 +140,7 @@ namespace OpenIddict.Core if (string.IsNullOrEmpty(type)) { await Store.SetClientTypeAsync(application, string.IsNullOrEmpty(secret) ? - OpenIddictConstants.ClientTypes.Public : - OpenIddictConstants.ClientTypes.Confidential, cancellationToken); + ClientTypes.Public : ClientTypes.Confidential, cancellationToken); } // If a client secret was provided, obfuscate it. @@ -479,7 +479,7 @@ namespace OpenIddict.Core var type = await Store.GetConsentTypeAsync(application, cancellationToken); if (string.IsNullOrEmpty(type)) { - return OpenIddictConstants.ConsentTypes.Explicit; + return ConsentTypes.Explicit; } return type; @@ -669,7 +669,7 @@ namespace OpenIddict.Core return false; } - return string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase); + return string.Equals(type, ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase); } /// @@ -691,7 +691,7 @@ namespace OpenIddict.Core return false; } - return string.Equals(type, OpenIddictConstants.ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase); + return string.Equals(type, ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase); } /// @@ -714,7 +714,7 @@ namespace OpenIddict.Core return true; } - return string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase); + return string.Equals(type, ClientTypes.Public, StringComparison.OrdinalIgnoreCase); } /// @@ -1027,9 +1027,9 @@ namespace OpenIddict.Core else { // Ensure the application type is supported by the manager. - if (!string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(type, ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) { yield return new ValidationResult("Only 'confidential', 'hybrid' or 'public' applications are " + "supported by the default application manager."); @@ -1037,15 +1037,13 @@ namespace OpenIddict.Core // Ensure a client secret was specified if the client is a confidential application. var secret = await Store.GetClientSecretAsync(application, cancellationToken); - if (string.IsNullOrEmpty(secret) && - string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrEmpty(secret) && string.Equals(type, ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase)) { yield return new ValidationResult("The client secret cannot be null or empty for a confidential application."); } // Ensure no client secret was specified if the client is a public application. - else if (!string.IsNullOrEmpty(secret) && - string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + else if (!string.IsNullOrEmpty(secret) && string.Equals(type, ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) { yield return new ValidationResult("A client secret cannot be associated with a public application."); } diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs index 5db97b2d..f0e84bed 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs @@ -18,6 +18,7 @@ using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; +using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictExceptions; namespace OpenIddict.Core @@ -110,7 +111,7 @@ namespace OpenIddict.Core // If no status was explicitly specified, assume that the authorization is valid. if (string.IsNullOrEmpty(await Store.GetStatusAsync(authorization, cancellationToken))) { - await Store.SetStatusAsync(authorization, OpenIddictConstants.Statuses.Valid, cancellationToken); + await Store.SetStatusAsync(authorization, Statuses.Valid, cancellationToken); } var results = await ValidateAsync(authorization, cancellationToken).ToListAsync(cancellationToken); @@ -204,7 +205,7 @@ namespace OpenIddict.Core { ApplicationId = client, Principal = principal, - Status = OpenIddictConstants.Statuses.Valid, + Status = Statuses.Valid, Subject = subject, Type = type }; @@ -878,12 +879,12 @@ namespace OpenIddict.Core } var status = await Store.GetStatusAsync(authorization, cancellationToken); - if (string.Equals(status, OpenIddictConstants.Statuses.Revoked, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(status, Statuses.Revoked, StringComparison.OrdinalIgnoreCase)) { return true; } - await Store.SetStatusAsync(authorization, OpenIddictConstants.Statuses.Revoked, cancellationToken); + await Store.SetStatusAsync(authorization, Statuses.Revoked, cancellationToken); try { @@ -997,8 +998,8 @@ namespace OpenIddict.Core yield return new ValidationResult("The authorization type cannot be null or empty."); } - else if (!string.Equals(type, OpenIddictConstants.AuthorizationTypes.AdHoc, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.AuthorizationTypes.Permanent, StringComparison.OrdinalIgnoreCase)) + else if (!string.Equals(type, AuthorizationTypes.AdHoc, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, AuthorizationTypes.Permanent, StringComparison.OrdinalIgnoreCase)) { yield return new ValidationResult("The specified authorization type is not supported by the default token manager."); } @@ -1018,7 +1019,7 @@ namespace OpenIddict.Core break; } - if (scope.Contains(OpenIddictConstants.Separators.Space[0])) + if (scope.Contains(Separators.Space[0])) { yield return new ValidationResult("Scopes cannot contain spaces."); diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs index 2d2b17f8..be963349 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs @@ -17,6 +17,7 @@ using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; +using static OpenIddict.Abstractions.OpenIddictConstants; namespace OpenIddict.Core { @@ -688,7 +689,7 @@ namespace OpenIddict.Core yield return new ValidationResult("The scope name cannot be null or empty."); } - else if (name.Contains(OpenIddictConstants.Separators.Space[0])) + else if (name.Contains(Separators.Space[0])) { yield return new ValidationResult("The scope name cannot contain spaces."); } diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs index 2b177700..15b586c8 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs @@ -18,6 +18,7 @@ using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; +using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictExceptions; namespace OpenIddict.Core @@ -110,7 +111,7 @@ namespace OpenIddict.Core // If no status was explicitly specified, assume that the token is valid. if (string.IsNullOrEmpty(await Store.GetStatusAsync(token, cancellationToken))) { - await Store.SetStatusAsync(token, OpenIddictConstants.Statuses.Valid, cancellationToken); + await Store.SetStatusAsync(token, Statuses.Valid, cancellationToken); } // If a reference identifier was set, obfuscate it. @@ -1022,12 +1023,12 @@ namespace OpenIddict.Core } var status = await Store.GetStatusAsync(token, cancellationToken); - if (string.Equals(status, OpenIddictConstants.Statuses.Redeemed, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(status, Statuses.Redeemed, StringComparison.OrdinalIgnoreCase)) { return true; } - await Store.SetStatusAsync(token, OpenIddictConstants.Statuses.Redeemed, cancellationToken); + await Store.SetStatusAsync(token, Statuses.Redeemed, cancellationToken); try { @@ -1070,12 +1071,12 @@ namespace OpenIddict.Core } var status = await Store.GetStatusAsync(token, cancellationToken); - if (string.Equals(status, OpenIddictConstants.Statuses.Rejected, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(status, Statuses.Rejected, StringComparison.OrdinalIgnoreCase)) { return true; } - await Store.SetStatusAsync(token, OpenIddictConstants.Statuses.Rejected, cancellationToken); + await Store.SetStatusAsync(token, Statuses.Rejected, cancellationToken); try { @@ -1118,12 +1119,12 @@ namespace OpenIddict.Core } var status = await Store.GetStatusAsync(token, cancellationToken); - if (string.Equals(status, OpenIddictConstants.Statuses.Revoked, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(status, Statuses.Revoked, StringComparison.OrdinalIgnoreCase)) { return true; } - await Store.SetStatusAsync(token, OpenIddictConstants.Statuses.Revoked, cancellationToken); + await Store.SetStatusAsync(token, Statuses.Revoked, cancellationToken); try { @@ -1266,11 +1267,11 @@ namespace OpenIddict.Core yield return new ValidationResult("The token type cannot be null or empty."); } - else if (!string.Equals(type, OpenIddictConstants.TokenUsages.AccessToken, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.TokenUsages.AuthorizationCode, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.TokenUsages.DeviceCode, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.TokenUsages.RefreshToken, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.TokenUsages.UserCode, StringComparison.OrdinalIgnoreCase)) + else if (!string.Equals(type, TokenTypeHints.AccessToken, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, TokenTypeHints.AuthorizationCode, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, TokenTypeHints.DeviceCode, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, TokenTypeHints.UserCode, StringComparison.OrdinalIgnoreCase)) { yield return new ValidationResult("The specified token type is not supported by the default token manager."); } @@ -1281,8 +1282,8 @@ namespace OpenIddict.Core } if (string.IsNullOrEmpty(await Store.GetSubjectAsync(token, cancellationToken)) && - !string.Equals(type, OpenIddictConstants.TokenUsages.DeviceCode, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.TokenUsages.UserCode, StringComparison.OrdinalIgnoreCase)) + !string.Equals(type, TokenTypeHints.DeviceCode, StringComparison.OrdinalIgnoreCase) && + !string.Equals(type, TokenTypeHints.UserCode, StringComparison.OrdinalIgnoreCase)) { yield return new ValidationResult("The subject cannot be null or empty."); } diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConstants.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConstants.cs index 87d2e5b9..2ec90bba 100644 --- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConstants.cs +++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConstants.cs @@ -27,8 +27,6 @@ namespace OpenIddict.Server.DataProtection public const string RefreshTokenLifetime = ".refresh_token_lifetime"; public const string Resources = ".resources"; public const string Scopes = ".scopes"; - public const string TokenId = ".token_id"; - public const string TokenUsage = ".token_usage"; } public static class Purposes diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs index 984e4589..1ca71107 100644 --- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs +++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs @@ -44,6 +44,7 @@ namespace OpenIddict.Server.DataProtection .SetCreationDate(GetDateProperty(properties, Properties.Issued)) .SetExpirationDate(GetDateProperty(properties, Properties.Expires)) .SetPresenters(GetArrayProperty(properties, Properties.Presenters)) + .SetResources(GetArrayProperty(properties, Properties.Resources)) .SetScopes(GetArrayProperty(properties, Properties.Scopes)) .SetClaim(Claims.Private.AccessTokenLifetime, GetProperty(properties, Properties.AccessTokenLifetime)) @@ -219,6 +220,7 @@ namespace OpenIddict.Server.DataProtection SetArrayProperty(properties, Properties.Audiences, principal.GetAudiences()); SetArrayProperty(properties, Properties.Presenters, principal.GetPresenters()); + SetArrayProperty(properties, Properties.Resources, principal.GetResources()); SetArrayProperty(properties, Properties.Scopes, principal.GetScopes()); // Copy the principal and exclude the claim that were mapped to authentication properties. @@ -238,6 +240,7 @@ namespace OpenIddict.Server.DataProtection Claims.Private.Presenters => false, Claims.Private.RedirectUri => false, Claims.Private.RefreshTokenLifetime => false, + Claims.Private.Resources => false, Claims.Private.Scopes => false, Claims.Private.TokenId => false, diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs index e7ac6d3e..2c740ed0 100644 --- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs +++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs @@ -86,11 +86,11 @@ namespace OpenIddict.Server.DataProtection // If the token cannot be validated, don't return an error to allow another handle to validate it. var principal = !string.IsNullOrEmpty(context.TokenType) ? ValidateToken(context.Token, context.TokenType) : - ValidateToken(context.Token, TokenUsages.AccessToken) ?? - ValidateToken(context.Token, TokenUsages.RefreshToken) ?? - ValidateToken(context.Token, TokenUsages.AuthorizationCode) ?? - ValidateToken(context.Token, TokenUsages.DeviceCode) ?? - ValidateToken(context.Token, TokenUsages.UserCode); + ValidateToken(context.Token, TokenTypeHints.AccessToken) ?? + ValidateToken(context.Token, TokenTypeHints.RefreshToken) ?? + ValidateToken(context.Token, TokenTypeHints.AuthorizationCode) ?? + ValidateToken(context.Token, TokenTypeHints.DeviceCode) ?? + ValidateToken(context.Token, TokenTypeHints.UserCode); if (principal == null) { return default; @@ -108,26 +108,26 @@ namespace OpenIddict.Server.DataProtection // Create a Data Protection protector using the provider registered in the options. var protector = _options.CurrentValue.DataProtectionProvider.CreateProtector(type switch { - TokenUsages.AccessToken when context.Options.UseReferenceAccessTokens + TokenTypeHints.AccessToken when context.Options.UseReferenceAccessTokens => new[] { Handlers.Server, Formats.AccessToken, Features.ReferenceTokens, Schemes.Server }, - TokenUsages.AuthorizationCode when !context.Options.DisableTokenStorage + TokenTypeHints.AuthorizationCode when !context.Options.DisableTokenStorage => new[] { Handlers.Server, Formats.AuthorizationCode, Features.ReferenceTokens, Schemes.Server }, - TokenUsages.DeviceCode when !context.Options.DisableTokenStorage + TokenTypeHints.DeviceCode when !context.Options.DisableTokenStorage => new[] { Handlers.Server, Formats.DeviceCode, Features.ReferenceTokens, Schemes.Server }, - TokenUsages.RefreshToken when !context.Options.DisableTokenStorage + TokenTypeHints.RefreshToken when !context.Options.DisableTokenStorage => new[] { Handlers.Server, Formats.RefreshToken, Features.ReferenceTokens, Schemes.Server }, - TokenUsages.UserCode when !context.Options.DisableTokenStorage + TokenTypeHints.UserCode when !context.Options.DisableTokenStorage => new[] { Handlers.Server, Formats.UserCode, Features.ReferenceTokens, Schemes.Server }, - TokenUsages.AccessToken => new[] { Handlers.Server, Formats.AccessToken, Schemes.Server }, - TokenUsages.AuthorizationCode => new[] { Handlers.Server, Formats.AuthorizationCode, Schemes.Server }, - TokenUsages.DeviceCode => new[] { Handlers.Server, Formats.DeviceCode, Schemes.Server }, - TokenUsages.RefreshToken => new[] { Handlers.Server, Formats.RefreshToken, Schemes.Server }, - TokenUsages.UserCode => new[] { Handlers.Server, Formats.UserCode, Schemes.Server }, + TokenTypeHints.AccessToken => new[] { Handlers.Server, Formats.AccessToken, Schemes.Server }, + TokenTypeHints.AuthorizationCode => new[] { Handlers.Server, Formats.AuthorizationCode, Schemes.Server }, + TokenTypeHints.DeviceCode => new[] { Handlers.Server, Formats.DeviceCode, Schemes.Server }, + TokenTypeHints.RefreshToken => new[] { Handlers.Server, Formats.RefreshToken, Schemes.Server }, + TokenTypeHints.UserCode => new[] { Handlers.Server, Formats.UserCode, Schemes.Server }, _ => throw new InvalidOperationException("The specified token type is not supported.") }); @@ -139,7 +139,7 @@ namespace OpenIddict.Server.DataProtection // Note: since the data format relies on a data protector using different "purposes" strings // per token type, the token processed at this stage is guaranteed to be of the expected type. - return _options.CurrentValue.Formatter.ReadToken(reader)?.SetClaim(Claims.Private.TokenUsage, type); + return _options.CurrentValue.Formatter.ReadToken(reader)?.SetClaim(Claims.Private.TokenType, type); } catch (Exception exception) diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs index 8887561c..e5b5e668 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs @@ -1035,7 +1035,7 @@ namespace OpenIddict.Server } context.TokenId = context.Principal.GetClaim(Claims.JwtId); - context.TokenUsage = context.Principal.GetTokenUsage(); + context.TokenUsage = context.Principal.GetTokenType(); context.Subject = context.Principal.GetClaim(Claims.Subject); context.IssuedAt = context.NotBefore = context.Principal.GetCreationDate(); diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.cs index 28be5ec0..3ed24a3b 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.cs @@ -198,8 +198,8 @@ namespace OpenIddict.Server var (token, type) = context.EndpointType switch { - OpenIddictServerEndpointType.Authorization => (context.Request.IdTokenHint, TokenUsages.IdToken), - OpenIddictServerEndpointType.Logout => (context.Request.IdTokenHint, TokenUsages.IdToken), + OpenIddictServerEndpointType.Authorization => (context.Request.IdTokenHint, TokenTypeHints.IdToken), + OpenIddictServerEndpointType.Logout => (context.Request.IdTokenHint, TokenTypeHints.IdToken), // Generic tokens received by the introspection and revocation can be of any type. // Additional token type filtering is made by the endpoint themselves, if needed. @@ -207,15 +207,15 @@ namespace OpenIddict.Server OpenIddictServerEndpointType.Revocation => (context.Request.Token, null), OpenIddictServerEndpointType.Token when context.Request.IsAuthorizationCodeGrantType() - => (context.Request.Code, TokenUsages.AuthorizationCode), + => (context.Request.Code, TokenTypeHints.AuthorizationCode), OpenIddictServerEndpointType.Token when context.Request.IsDeviceCodeGrantType() - => (context.Request.DeviceCode, TokenUsages.DeviceCode), + => (context.Request.DeviceCode, TokenTypeHints.DeviceCode), OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType() - => (context.Request.RefreshToken, TokenUsages.RefreshToken), + => (context.Request.RefreshToken, TokenTypeHints.RefreshToken), - OpenIddictServerEndpointType.Userinfo => (context.Request.AccessToken, TokenUsages.AccessToken), + OpenIddictServerEndpointType.Userinfo => (context.Request.AccessToken, TokenTypeHints.AccessToken), - OpenIddictServerEndpointType.Verification => (context.Request.UserCode, TokenUsages.UserCode), + OpenIddictServerEndpointType.Verification => (context.Request.UserCode, TokenTypeHints.UserCode), _ => (null, null) }; @@ -279,7 +279,7 @@ namespace OpenIddict.Server throw new ArgumentNullException(nameof(context)); } - if (!string.Equals(context.TokenType, TokenUsages.UserCode, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(context.TokenType, TokenTypeHints.UserCode, StringComparison.OrdinalIgnoreCase)) { return default; } @@ -445,13 +445,13 @@ namespace OpenIddict.Server { context.TokenType switch { - TokenUsages.AccessToken => JsonWebTokenTypes.AccessToken, - TokenUsages.IdToken => JsonWebTokenTypes.IdentityToken, + TokenTypeHints.AccessToken => JsonWebTokenTypes.AccessToken, + TokenTypeHints.IdToken => JsonWebTokenTypes.IdentityToken, - TokenUsages.AuthorizationCode => JsonWebTokenTypes.Private.AuthorizationCode, - TokenUsages.DeviceCode => JsonWebTokenTypes.Private.DeviceCode, - TokenUsages.RefreshToken => JsonWebTokenTypes.Private.RefreshToken, - TokenUsages.UserCode => JsonWebTokenTypes.Private.UserCode, + TokenTypeHints.AuthorizationCode => JsonWebTokenTypes.Private.AuthorizationCode, + TokenTypeHints.DeviceCode => JsonWebTokenTypes.Private.DeviceCode, + TokenTypeHints.RefreshToken => JsonWebTokenTypes.Private.RefreshToken, + TokenTypeHints.UserCode => JsonWebTokenTypes.Private.UserCode, _ => throw new InvalidOperationException("The token type is not supported.") } @@ -478,15 +478,15 @@ namespace OpenIddict.Server context.Principal = new ClaimsPrincipal(result.ClaimsIdentity); // Store the token type as a special private claim. - context.Principal.SetClaim(Claims.Private.TokenUsage, token.Typ switch + context.Principal.SetClaim(Claims.Private.TokenType, token.Typ switch { - JsonWebTokenTypes.AccessToken => TokenUsages.AccessToken, - JsonWebTokenTypes.IdentityToken => TokenUsages.IdToken, + JsonWebTokenTypes.AccessToken => TokenTypeHints.AccessToken, + JsonWebTokenTypes.IdentityToken => TokenTypeHints.IdToken, - JsonWebTokenTypes.Private.AuthorizationCode => TokenUsages.AuthorizationCode, - JsonWebTokenTypes.Private.DeviceCode => TokenUsages.DeviceCode, - JsonWebTokenTypes.Private.RefreshToken => TokenUsages.RefreshToken, - JsonWebTokenTypes.Private.UserCode => TokenUsages.UserCode, + JsonWebTokenTypes.Private.AuthorizationCode => TokenTypeHints.AuthorizationCode, + JsonWebTokenTypes.Private.DeviceCode => TokenTypeHints.DeviceCode, + JsonWebTokenTypes.Private.RefreshToken => TokenTypeHints.RefreshToken, + JsonWebTokenTypes.Private.UserCode => TokenTypeHints.UserCode, _ => throw new InvalidOperationException("The token type is not supported.") }); @@ -497,6 +497,19 @@ namespace OpenIddict.Server context.Principal.SetDestinations(destinations); } + if (context.Principal.IsAccessToken()) + { + // Map the standardized "azp" and "scope" claims to their "oi_" equivalent so that + // the ClaimsPrincipal extensions exposed by OpenIddict return consistent results. + context.Principal.SetPresenters(context.Principal.GetClaims(Claims.AuthorizedParty)); + + // Note: starting in OpenIddict 3.0, the public "scope" claim is formatted + // as a unique space-separated string containing all the granted scopes. + // Visit https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt-03 for more information. + context.Principal.SetScopes(context.Principal.GetClaim(Claims.Scope) + ?.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries)); + } + context.Logger.LogTrace("The token '{Token}' was successfully validated and the following claims " + "could be extracted: {Claims}.", context.Token, context.Principal.Claims); @@ -563,7 +576,7 @@ namespace OpenIddict.Server .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token)) .SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token)) .SetInternalTokenId(await _tokenManager.GetIdAsync(token)) - .SetClaim(Claims.Private.TokenUsage, await _tokenManager.GetTypeAsync(token)); + .SetClaim(Claims.Private.TokenType, await _tokenManager.GetTypeAsync(token)); } } @@ -801,7 +814,7 @@ namespace OpenIddict.Server .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token)) .SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token)) .SetInternalTokenId(await _tokenManager.GetIdAsync(token)) - .SetClaim(Claims.Private.TokenUsage, await _tokenManager.GetTypeAsync(token)); + .SetClaim(Claims.Private.TokenType, await _tokenManager.GetTypeAsync(token)); async ValueTask TryRevokeAuthorizationChainAsync(string identifier) { @@ -2791,7 +2804,7 @@ namespace OpenIddict.Server ReferenceId = Base64UrlEncoder.Encode(data), Status = Statuses.Valid, Subject = context.AccessTokenPrincipal.GetClaim(Claims.Subject), - Type = TokenUsages.AccessToken + Type = TokenTypeHints.AccessToken }; // If the client application is known, associate it with the token. @@ -2968,7 +2981,7 @@ namespace OpenIddict.Server ReferenceId = Base64UrlEncoder.Encode(data), Status = Statuses.Valid, Subject = context.AuthorizationCodePrincipal.GetClaim(Claims.Subject), - Type = TokenUsages.AuthorizationCode + Type = TokenTypeHints.AuthorizationCode }; // If the client application is known, associate it with the token. @@ -3150,7 +3163,7 @@ namespace OpenIddict.Server ReferenceId = Base64UrlEncoder.Encode(data), Status = Statuses.Inactive, Subject = null, // Device codes are not bound to a user, which is not known until the user code is populated. - Type = TokenUsages.DeviceCode + Type = TokenTypeHints.DeviceCode }; // If the client application is known, associate it with the token. @@ -3423,7 +3436,7 @@ namespace OpenIddict.Server ReferenceId = Base64UrlEncoder.Encode(data), Status = Statuses.Valid, Subject = context.RefreshTokenPrincipal.GetClaim(Claims.Subject), - Type = TokenUsages.RefreshToken + Type = TokenTypeHints.RefreshToken }; // If the client application is known, associate it with the token. @@ -3641,7 +3654,7 @@ namespace OpenIddict.Server ReferenceId = builder.ToString(), Status = Statuses.Valid, Subject = null, // User codes are not bound to a user until authorization is granted. - Type = TokenUsages.UserCode + Type = TokenTypeHints.UserCode }; // If the client application is known, associate it with the token. diff --git a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConstants.cs b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConstants.cs index 7fbe1fbf..0d181d8d 100644 --- a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConstants.cs +++ b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConstants.cs @@ -27,8 +27,6 @@ namespace OpenIddict.Validation.DataProtection public const string RefreshTokenLifetime = ".refresh_token_lifetime"; public const string Resources = ".resources"; public const string Scopes = ".scopes"; - public const string TokenId = ".token_id"; - public const string TokenUsage = ".token_usage"; } public static class Purposes diff --git a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs index 49064d39..b47676b1 100644 --- a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs +++ b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs @@ -10,8 +10,8 @@ using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Security.Claims; -using JetBrains.Annotations; using System.Text.Json; +using JetBrains.Annotations; using OpenIddict.Abstractions; using static OpenIddict.Abstractions.OpenIddictConstants; using Properties = OpenIddict.Validation.DataProtection.OpenIddictValidationDataProtectionConstants.Properties; @@ -42,6 +42,7 @@ namespace OpenIddict.Validation.DataProtection .SetCreationDate(GetDateProperty(properties, Properties.Issued)) .SetExpirationDate(GetDateProperty(properties, Properties.Expires)) .SetPresenters(GetArrayProperty(properties, Properties.Presenters)) + .SetResources(GetArrayProperty(properties, Properties.Resources)) .SetScopes(GetArrayProperty(properties, Properties.Scopes)) .SetClaim(Claims.Private.AccessTokenLifetime, GetProperty(properties, Properties.AccessTokenLifetime)) diff --git a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionHandlers.cs b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionHandlers.cs index 1b15bc00..175c0957 100644 --- a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionHandlers.cs +++ b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionHandlers.cs @@ -102,7 +102,7 @@ namespace OpenIddict.Validation.DataProtection // Note: since the data format relies on a data protector using different "purposes" strings // per token type, the token processed at this stage is guaranteed to be of the expected type. - context.Principal = principal.SetClaim(Claims.Private.TokenUsage, TokenUsages.AccessToken); + context.Principal = principal.SetClaim(Claims.Private.TokenType, TokenTypeHints.AccessToken); context.Logger.LogTrace("The self-contained DP token '{Token}' was successfully validated and the following " + "claims could be extracted: {Claims}.", context.Token, context.Principal.Claims); diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs index a23cfe95..4f2edb15 100644 --- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs +++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs @@ -130,7 +130,7 @@ namespace OpenIddict.Validation } var type = await _tokenManager.GetTypeAsync(token); - if (!string.Equals(type, TokenUsages.AccessToken, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(type, TokenTypeHints.AccessToken, StringComparison.OrdinalIgnoreCase)) { context.Reject( error: Errors.InvalidToken, @@ -221,7 +221,17 @@ namespace OpenIddict.Validation // Attach the principal extracted from the token to the parent event context. context.Principal = new ClaimsPrincipal(result.ClaimsIdentity); - context.Principal.SetClaim(Claims.Private.TokenUsage, TokenUsages.AccessToken); + context.Principal.SetClaim(Claims.Private.TokenType, TokenTypeHints.AccessToken); + + // Map the standardized "azp" and "scope" claims to their "oi_" equivalent so that + // the ClaimsPrincipal extensions exposed by OpenIddict return consistent results. + context.Principal.SetPresenters(context.Principal.GetClaims(Claims.AuthorizedParty)); + + // Note: starting in OpenIddict 3.0, the public "scope" claim is formatted + // as a unique space-separated string containing all the granted scopes. + // Visit https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt-03 for more information. + context.Principal.SetScopes(context.Principal.GetClaim(Claims.Scope) + ?.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries)); context.Logger.LogTrace("The self-contained JWT token '{Token}' was successfully validated and the following " + "claims could be extracted: {Claims}.", context.Token, context.Principal.Claims); @@ -286,7 +296,7 @@ namespace OpenIddict.Validation .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token)) .SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token)) .SetInternalTokenId(await _tokenManager.GetIdAsync(token)) - .SetClaim(Claims.Private.TokenUsage, await _tokenManager.GetTypeAsync(token)); + .SetClaim(Claims.Private.TokenType, await _tokenManager.GetTypeAsync(token)); } } diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs index 68dc2d72..04c61260 100644 --- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs +++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs @@ -1906,13 +1906,13 @@ namespace OpenIddict.Abstractions.Tests.Primitives } [Fact] - public void GetTokenUsage_ThrowsAnExceptionForNullPrincipal() + public void GetTokenType_ThrowsAnExceptionForNullPrincipal() { // Arrange var principal = (ClaimsPrincipal) null; // Act and assert - var exception = Assert.Throws(() => principal.GetTokenUsage()); + var exception = Assert.Throws(() => principal.GetTokenType()); Assert.Equal("principal", exception.ParamName); } @@ -1920,16 +1920,16 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null)] [InlineData("access_token")] - public void GetTokenUsage_ReturnsExpectedResult(string usage) + public void GetTokenType_ReturnsExpectedResult(string type) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); - principal.SetClaim(Claims.Private.TokenUsage, usage); + principal.SetClaim(Claims.Private.TokenType, type); // Act and assert - Assert.Equal(usage, principal.GetTokenUsage()); + Assert.Equal(type, principal.GetTokenType()); } [Fact] @@ -2203,19 +2203,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null, false)] [InlineData("unknown", false)] - [InlineData(TokenUsages.AccessToken, true)] - [InlineData(TokenUsages.AuthorizationCode, false)] - [InlineData(TokenUsages.DeviceCode, false)] - [InlineData(TokenUsages.IdToken, false)] - [InlineData(TokenUsages.RefreshToken, false)] - [InlineData(TokenUsages.UserCode, false)] - public void IsAccessToken_ReturnsExpectedResult(string usage, bool result) + [InlineData(TokenTypeHints.AccessToken, true)] + [InlineData(TokenTypeHints.AuthorizationCode, false)] + [InlineData(TokenTypeHints.DeviceCode, false)] + [InlineData(TokenTypeHints.IdToken, false)] + [InlineData(TokenTypeHints.RefreshToken, false)] + [InlineData(TokenTypeHints.UserCode, false)] + public void IsAccessToken_ReturnsExpectedResult(string type, bool result) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); - principal.SetClaim(Claims.Private.TokenUsage, usage); + principal.SetClaim(Claims.Private.TokenType, type); // Act and assert Assert.Equal(result, principal.IsAccessToken()); @@ -2236,19 +2236,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null, false)] [InlineData("unknown", false)] - [InlineData(TokenUsages.AccessToken, false)] - [InlineData(TokenUsages.AuthorizationCode, true)] - [InlineData(TokenUsages.DeviceCode, false)] - [InlineData(TokenUsages.IdToken, false)] - [InlineData(TokenUsages.RefreshToken, false)] - [InlineData(TokenUsages.UserCode, false)] - public void IsAuthorizationCode_ReturnsExpectedResult(string usage, bool result) + [InlineData(TokenTypeHints.AccessToken, false)] + [InlineData(TokenTypeHints.AuthorizationCode, true)] + [InlineData(TokenTypeHints.DeviceCode, false)] + [InlineData(TokenTypeHints.IdToken, false)] + [InlineData(TokenTypeHints.RefreshToken, false)] + [InlineData(TokenTypeHints.UserCode, false)] + public void IsAuthorizationCode_ReturnsExpectedResult(string type, bool result) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); - principal.SetClaim(Claims.Private.TokenUsage, usage); + principal.SetClaim(Claims.Private.TokenType, type); // Act and assert Assert.Equal(result, principal.IsAuthorizationCode()); @@ -2269,19 +2269,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null, false)] [InlineData("unknown", false)] - [InlineData(TokenUsages.AccessToken, false)] - [InlineData(TokenUsages.AuthorizationCode, false)] - [InlineData(TokenUsages.DeviceCode, true)] - [InlineData(TokenUsages.IdToken, false)] - [InlineData(TokenUsages.RefreshToken, false)] - [InlineData(TokenUsages.UserCode, false)] - public void IsDeviceCode_ReturnsExpectedResult(string usage, bool result) + [InlineData(TokenTypeHints.AccessToken, false)] + [InlineData(TokenTypeHints.AuthorizationCode, false)] + [InlineData(TokenTypeHints.DeviceCode, true)] + [InlineData(TokenTypeHints.IdToken, false)] + [InlineData(TokenTypeHints.RefreshToken, false)] + [InlineData(TokenTypeHints.UserCode, false)] + public void IsDeviceCode_ReturnsExpectedResult(string type, bool result) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); - principal.SetClaim(Claims.Private.TokenUsage, usage); + principal.SetClaim(Claims.Private.TokenType, type); // Act and assert Assert.Equal(result, principal.IsDeviceCode()); @@ -2302,19 +2302,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null, false)] [InlineData("unknown", false)] - [InlineData(TokenUsages.AccessToken, false)] - [InlineData(TokenUsages.AuthorizationCode, false)] - [InlineData(TokenUsages.DeviceCode, false)] - [InlineData(TokenUsages.IdToken, true)] - [InlineData(TokenUsages.RefreshToken, false)] - [InlineData(TokenUsages.UserCode, false)] - public void IsIdentityToken_ReturnsExpectedResult(string usage, bool result) + [InlineData(TokenTypeHints.AccessToken, false)] + [InlineData(TokenTypeHints.AuthorizationCode, false)] + [InlineData(TokenTypeHints.DeviceCode, false)] + [InlineData(TokenTypeHints.IdToken, true)] + [InlineData(TokenTypeHints.RefreshToken, false)] + [InlineData(TokenTypeHints.UserCode, false)] + public void IsIdentityToken_ReturnsExpectedResult(string type, bool result) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); - principal.SetClaim(Claims.Private.TokenUsage, usage); + principal.SetClaim(Claims.Private.TokenType, type); // Act and assert Assert.Equal(result, principal.IsIdentityToken()); @@ -2335,17 +2335,17 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null, false)] [InlineData("unknown", false)] - [InlineData(TokenUsages.AccessToken, false)] - [InlineData(TokenUsages.AuthorizationCode, false)] - [InlineData(TokenUsages.IdToken, false)] - [InlineData(TokenUsages.RefreshToken, true)] - public void IsRefreshToken_ReturnsExpectedResult(string usage, bool result) + [InlineData(TokenTypeHints.AccessToken, false)] + [InlineData(TokenTypeHints.AuthorizationCode, false)] + [InlineData(TokenTypeHints.IdToken, false)] + [InlineData(TokenTypeHints.RefreshToken, true)] + public void IsRefreshToken_ReturnsExpectedResult(string type, bool result) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); - principal.SetClaim(Claims.Private.TokenUsage, usage); + principal.SetClaim(Claims.Private.TokenType, type); // Act and assert Assert.Equal(result, principal.IsRefreshToken()); @@ -2366,19 +2366,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null, false)] [InlineData("unknown", false)] - [InlineData(TokenUsages.AccessToken, false)] - [InlineData(TokenUsages.AuthorizationCode, false)] - [InlineData(TokenUsages.DeviceCode, false)] - [InlineData(TokenUsages.IdToken, false)] - [InlineData(TokenUsages.RefreshToken, false)] - [InlineData(TokenUsages.UserCode, true)] - public void IsUserCode_ReturnsExpectedResult(string usage, bool result) + [InlineData(TokenTypeHints.AccessToken, false)] + [InlineData(TokenTypeHints.AuthorizationCode, false)] + [InlineData(TokenTypeHints.DeviceCode, false)] + [InlineData(TokenTypeHints.IdToken, false)] + [InlineData(TokenTypeHints.RefreshToken, false)] + [InlineData(TokenTypeHints.UserCode, true)] + public void IsUserCode_ReturnsExpectedResult(string type, bool result) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); - principal.SetClaim(Claims.Private.TokenUsage, usage); + principal.SetClaim(Claims.Private.TokenType, type); // Act and assert Assert.Equal(result, principal.IsUserCode()); @@ -2973,13 +2973,13 @@ namespace OpenIddict.Abstractions.Tests.Primitives } [Fact] - public void SetTokenUsage_ThrowsAnExceptionForNullPrincipal() + public void SetTokenType_ThrowsAnExceptionForNullPrincipal() { // Arrange var principal = (ClaimsPrincipal) null; // Act and assert - var exception = Assert.Throws(() => principal.SetTokenUsage(null)); + var exception = Assert.Throws(() => principal.SetTokenType(null)); Assert.Equal("principal", exception.ParamName); } @@ -2987,17 +2987,17 @@ namespace OpenIddict.Abstractions.Tests.Primitives [Theory] [InlineData(null)] [InlineData("access_token")] - public void SetTokenUsage_AddsUsage(string usage) + public void SetTokenType_AddsType(string type) { // Arrange var identity = new ClaimsIdentity(); var principal = new ClaimsPrincipal(identity); // Act - principal.SetTokenUsage(usage); + principal.SetTokenType(type); // Assert - Assert.Equal(usage, principal.GetClaim(Claims.Private.TokenUsage)); + Assert.Equal(type, principal.GetClaim(Claims.Private.TokenType)); } private TimeSpan? ParseLifeTime(string lifetime) diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs index 06730cb4..2a7e61fb 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs @@ -398,7 +398,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetExpirationDate(DateTimeOffset.UtcNow - TimeSpan.FromDays(1)); @@ -436,7 +436,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetExpirationDate(DateTimeOffset.UtcNow - TimeSpan.FromDays(1)); @@ -473,7 +473,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters(Enumerable.Empty()); @@ -512,7 +512,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Contoso"); @@ -550,7 +550,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Contoso"); @@ -588,7 +588,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -628,7 +628,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -669,7 +669,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -712,7 +712,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -755,7 +755,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetClaim(Claims.Subject, "Bob le Magnifique") @@ -796,7 +796,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -836,7 +836,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -876,7 +876,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetScopes(Enumerable.Empty()); @@ -914,7 +914,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetScopes("profile", "email"); @@ -1552,7 +1552,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -1604,7 +1604,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103"); @@ -1648,7 +1648,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetInternalTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); @@ -1706,7 +1706,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -1760,7 +1760,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -1828,7 +1828,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103"); @@ -1876,7 +1876,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -1959,7 +1959,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") @@ -2049,7 +2049,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -2136,7 +2136,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -2198,7 +2198,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -2271,7 +2271,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -2319,7 +2319,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -2404,7 +2404,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") @@ -2471,7 +2471,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -2556,7 +2556,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetPresenters("Fabrikam") @@ -2637,7 +2637,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") @@ -2708,7 +2708,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("8xLOxBtZp8", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs index 2aa9d860..33feb6c8 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs @@ -191,7 +191,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("id_token", context.Token); - Assert.Equal(TokenUsages.IdToken, context.TokenType); + Assert.Equal(TokenTypeHints.IdToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetClaim(Claims.Subject, "Bob le Magnifique"); @@ -295,7 +295,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("authorization_code", context.Token); - Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); + Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetClaim(Claims.Subject, "Bob le Magnifique") @@ -400,7 +400,7 @@ namespace OpenIddict.Server.FunctionalTests builder.UseInlineHandler(context => { Assert.Equal("refresh_token", context.Token); - Assert.Equal(TokenUsages.RefreshToken, context.TokenType); + Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) .SetClaim(Claims.Subject, "Bob le Magnifique");