Browse Source

Automatically map the scope/azp access token claims to their OpenIddict private claims equivalents

pull/879/head
Kévin Chalet 7 years ago
parent
commit
a25907cd52
  1. 28
      samples/Mvc.Server/Controllers/UserinfoController.cs
  2. 12
      src/OpenIddict.Abstractions/OpenIddictConstants.cs
  3. 28
      src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs
  4. 24
      src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
  5. 15
      src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
  6. 3
      src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
  7. 29
      src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
  8. 2
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConstants.cs
  9. 3
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs
  10. 32
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
  11. 2
      src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
  12. 69
      src/OpenIddict.Server/OpenIddictServerHandlers.cs
  13. 2
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConstants.cs
  14. 3
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs
  15. 2
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionHandlers.cs
  16. 16
      src/OpenIddict.Validation/OpenIddictValidationHandlers.cs
  17. 112
      test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs
  18. 64
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs
  19. 6
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs

28
samples/Mvc.Server/Controllers/UserinfoController.cs

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc;
using Mvc.Server.Models; using Mvc.Server.Models;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using OpenIddict.Server.AspNetCore; using OpenIddict.Server.AspNetCore;
using static OpenIddict.Abstractions.OpenIddictConstants;
namespace Mvc.Server.Controllers namespace Mvc.Server.Controllers
{ {
@ -15,9 +16,7 @@ namespace Mvc.Server.Controllers
private readonly UserManager<ApplicationUser> _userManager; private readonly UserManager<ApplicationUser> _userManager;
public UserinfoController(UserManager<ApplicationUser> userManager) public UserinfoController(UserManager<ApplicationUser> userManager)
{ => _userManager = userManager;
_userManager = userManager;
}
// //
// GET: /api/userinfo // GET: /api/userinfo
@ -31,24 +30,25 @@ namespace Mvc.Server.Controllers
return Challenge(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); return Challenge(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
} }
var claims = new Dictionary<string, object>(StringComparer.Ordinal); var claims = new Dictionary<string, object>(StringComparer.Ordinal)
{
// Note: the "sub" claim is a mandatory claim and must be included in the JSON response. // Note: the "sub" claim is a mandatory claim and must be included in the JSON response.
claims[OpenIddictConstants.Claims.Subject] = await _userManager.GetUserIdAsync(user); [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[Claims.Email] = await _userManager.GetEmailAsync(user);
claims[OpenIddictConstants.Claims.EmailVerified] = await _userManager.IsEmailConfirmedAsync(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[Claims.PhoneNumber] = await _userManager.GetPhoneNumberAsync(user);
claims[OpenIddictConstants.Claims.PhoneNumberVerified] = await _userManager.IsPhoneNumberConfirmedAsync(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); claims["roles"] = await _userManager.GetRolesAsync(user);
} }

12
src/OpenIddict.Abstractions/OpenIddictConstants.cs

@ -103,7 +103,7 @@ namespace OpenIddict.Abstractions
public const string Resources = "oi_rsrc"; public const string Resources = "oi_rsrc";
public const string Scopes = "oi_scp"; public const string Scopes = "oi_scp";
public const string TokenId = "oi_tkn_id"; 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"; public const string UserCodeLifetime = "oi_usrc_lft";
} }
} }
@ -428,15 +428,5 @@ namespace OpenIddict.Abstractions
{ {
public const string Bearer = "Bearer"; 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";
}
} }
} }

28
src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs

@ -1359,12 +1359,12 @@ namespace OpenIddict.Abstractions
=> principal.GetClaim(Claims.Private.TokenId); => principal.GetClaim(Claims.Private.TokenId);
/// <summary> /// <summary>
/// Gets the token usage associated with the claims principal. /// Gets the token type associated with the claims principal.
/// </summary> /// </summary>
/// <param name="principal">The claims principal.</param> /// <param name="principal">The claims principal.</param>
/// <returns>The token usage or <c>null</c> if the claim cannot be found.</returns> /// <returns>The token type or <c>null</c> if the claim cannot be found.</returns>
public static string GetTokenUsage([NotNull] this ClaimsPrincipal principal) public static string GetTokenType([NotNull] this ClaimsPrincipal principal)
=> principal.GetClaim(Claims.Private.TokenUsage); => principal.GetClaim(Claims.Private.TokenType);
/// <summary> /// <summary>
/// Gets a boolean value indicating whether the claims principal corresponds to an access token. /// 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)); throw new ArgumentNullException(nameof(principal));
} }
return string.Equals(principal.GetTokenUsage(), TokenUsages.AccessToken, StringComparison.OrdinalIgnoreCase); return string.Equals(principal.GetTokenType(), TokenTypeHints.AccessToken, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -1393,7 +1393,7 @@ namespace OpenIddict.Abstractions
throw new ArgumentNullException(nameof(principal)); throw new ArgumentNullException(nameof(principal));
} }
return string.Equals(principal.GetTokenUsage(), TokenUsages.AuthorizationCode, StringComparison.OrdinalIgnoreCase); return string.Equals(principal.GetTokenType(), TokenTypeHints.AuthorizationCode, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -1408,7 +1408,7 @@ namespace OpenIddict.Abstractions
throw new ArgumentNullException(nameof(principal)); throw new ArgumentNullException(nameof(principal));
} }
return string.Equals(principal.GetTokenUsage(), TokenUsages.DeviceCode, StringComparison.OrdinalIgnoreCase); return string.Equals(principal.GetTokenType(), TokenTypeHints.DeviceCode, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -1423,7 +1423,7 @@ namespace OpenIddict.Abstractions
throw new ArgumentNullException(nameof(principal)); throw new ArgumentNullException(nameof(principal));
} }
return string.Equals(principal.GetTokenUsage(), TokenUsages.IdToken, StringComparison.OrdinalIgnoreCase); return string.Equals(principal.GetTokenType(), TokenTypeHints.IdToken, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -1438,7 +1438,7 @@ namespace OpenIddict.Abstractions
throw new ArgumentNullException(nameof(principal)); throw new ArgumentNullException(nameof(principal));
} }
return string.Equals(principal.GetTokenUsage(), TokenUsages.RefreshToken, StringComparison.OrdinalIgnoreCase); return string.Equals(principal.GetTokenType(), TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -1453,7 +1453,7 @@ namespace OpenIddict.Abstractions
throw new ArgumentNullException(nameof(principal)); throw new ArgumentNullException(nameof(principal));
} }
return string.Equals(principal.GetTokenUsage(), TokenUsages.UserCode, StringComparison.OrdinalIgnoreCase); return string.Equals(principal.GetTokenType(), TokenTypeHints.UserCode, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -1887,13 +1887,13 @@ namespace OpenIddict.Abstractions
=> principal.SetClaim(Claims.Private.TokenId, identifier); => principal.SetClaim(Claims.Private.TokenId, identifier);
/// <summary> /// <summary>
/// Sets the token usage associated with the claims principal. /// Sets the token type associated with the claims principal.
/// </summary> /// </summary>
/// <param name="principal">The claims principal.</param> /// <param name="principal">The claims principal.</param>
/// <param name="usage">The token usage to store.</param> /// <param name="type">The token type to store.</param>
/// <returns>The claims principal.</returns> /// <returns>The claims principal.</returns>
public static ClaimsPrincipal SetTokenUsage([NotNull] this ClaimsPrincipal principal, string usage) public static ClaimsPrincipal SetTokenType([NotNull] this ClaimsPrincipal principal, string type)
=> principal.SetClaim(Claims.Private.TokenUsage, usage); => principal.SetClaim(Claims.Private.TokenType, type);
private static IEnumerable<string> GetValues(string source, char[] separators) private static IEnumerable<string> GetValues(string source, char[] separators)
{ {

24
src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs

@ -18,6 +18,7 @@ using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
#if !SUPPORTS_KEY_DERIVATION_WITH_SPECIFIED_HASH_ALGORITHM #if !SUPPORTS_KEY_DERIVATION_WITH_SPECIFIED_HASH_ALGORITHM
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
@ -139,8 +140,7 @@ namespace OpenIddict.Core
if (string.IsNullOrEmpty(type)) if (string.IsNullOrEmpty(type))
{ {
await Store.SetClientTypeAsync(application, string.IsNullOrEmpty(secret) ? await Store.SetClientTypeAsync(application, string.IsNullOrEmpty(secret) ?
OpenIddictConstants.ClientTypes.Public : ClientTypes.Public : ClientTypes.Confidential, cancellationToken);
OpenIddictConstants.ClientTypes.Confidential, cancellationToken);
} }
// If a client secret was provided, obfuscate it. // If a client secret was provided, obfuscate it.
@ -479,7 +479,7 @@ namespace OpenIddict.Core
var type = await Store.GetConsentTypeAsync(application, cancellationToken); var type = await Store.GetConsentTypeAsync(application, cancellationToken);
if (string.IsNullOrEmpty(type)) if (string.IsNullOrEmpty(type))
{ {
return OpenIddictConstants.ConsentTypes.Explicit; return ConsentTypes.Explicit;
} }
return type; return type;
@ -669,7 +669,7 @@ namespace OpenIddict.Core
return false; return false;
} }
return string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase); return string.Equals(type, ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -691,7 +691,7 @@ namespace OpenIddict.Core
return false; return false;
} }
return string.Equals(type, OpenIddictConstants.ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase); return string.Equals(type, ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -714,7 +714,7 @@ namespace OpenIddict.Core
return true; return true;
} }
return string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase); return string.Equals(type, ClientTypes.Public, StringComparison.OrdinalIgnoreCase);
} }
/// <summary> /// <summary>
@ -1027,9 +1027,9 @@ namespace OpenIddict.Core
else else
{ {
// Ensure the application type is supported by the manager. // Ensure the application type is supported by the manager.
if (!string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) && if (!string.Equals(type, ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase) && !string.Equals(type, ClientTypes.Hybrid, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) !string.Equals(type, ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
{ {
yield return new ValidationResult("Only 'confidential', 'hybrid' or 'public' applications are " + yield return new ValidationResult("Only 'confidential', 'hybrid' or 'public' applications are " +
"supported by the default application manager."); "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. // Ensure a client secret was specified if the client is a confidential application.
var secret = await Store.GetClientSecretAsync(application, cancellationToken); var secret = await Store.GetClientSecretAsync(application, cancellationToken);
if (string.IsNullOrEmpty(secret) && if (string.IsNullOrEmpty(secret) && string.Equals(type, ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
{ {
yield return new ValidationResult("The client secret cannot be null or empty for a confidential application."); 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. // Ensure no client secret was specified if the client is a public application.
else if (!string.IsNullOrEmpty(secret) && else if (!string.IsNullOrEmpty(secret) && string.Equals(type, ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
{ {
yield return new ValidationResult("A client secret cannot be associated with a public application."); yield return new ValidationResult("A client secret cannot be associated with a public application.");
} }

15
src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs

@ -18,6 +18,7 @@ using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
using static OpenIddict.Abstractions.OpenIddictExceptions; using static OpenIddict.Abstractions.OpenIddictExceptions;
namespace OpenIddict.Core namespace OpenIddict.Core
@ -110,7 +111,7 @@ namespace OpenIddict.Core
// If no status was explicitly specified, assume that the authorization is valid. // If no status was explicitly specified, assume that the authorization is valid.
if (string.IsNullOrEmpty(await Store.GetStatusAsync(authorization, cancellationToken))) 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); var results = await ValidateAsync(authorization, cancellationToken).ToListAsync(cancellationToken);
@ -204,7 +205,7 @@ namespace OpenIddict.Core
{ {
ApplicationId = client, ApplicationId = client,
Principal = principal, Principal = principal,
Status = OpenIddictConstants.Statuses.Valid, Status = Statuses.Valid,
Subject = subject, Subject = subject,
Type = type Type = type
}; };
@ -878,12 +879,12 @@ namespace OpenIddict.Core
} }
var status = await Store.GetStatusAsync(authorization, cancellationToken); 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; return true;
} }
await Store.SetStatusAsync(authorization, OpenIddictConstants.Statuses.Revoked, cancellationToken); await Store.SetStatusAsync(authorization, Statuses.Revoked, cancellationToken);
try try
{ {
@ -997,8 +998,8 @@ namespace OpenIddict.Core
yield return new ValidationResult("The authorization type cannot be null or empty."); yield return new ValidationResult("The authorization type cannot be null or empty.");
} }
else if (!string.Equals(type, OpenIddictConstants.AuthorizationTypes.AdHoc, StringComparison.OrdinalIgnoreCase) && else if (!string.Equals(type, AuthorizationTypes.AdHoc, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.AuthorizationTypes.Permanent, 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."); yield return new ValidationResult("The specified authorization type is not supported by the default token manager.");
} }
@ -1018,7 +1019,7 @@ namespace OpenIddict.Core
break; break;
} }
if (scope.Contains(OpenIddictConstants.Separators.Space[0])) if (scope.Contains(Separators.Space[0]))
{ {
yield return new ValidationResult("Scopes cannot contain spaces."); yield return new ValidationResult("Scopes cannot contain spaces.");

3
src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs

@ -17,6 +17,7 @@ using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
namespace OpenIddict.Core namespace OpenIddict.Core
{ {
@ -688,7 +689,7 @@ namespace OpenIddict.Core
yield return new ValidationResult("The scope name cannot be null or empty."); 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."); yield return new ValidationResult("The scope name cannot contain spaces.");
} }

29
src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs

@ -18,6 +18,7 @@ using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
using static OpenIddict.Abstractions.OpenIddictExceptions; using static OpenIddict.Abstractions.OpenIddictExceptions;
namespace OpenIddict.Core namespace OpenIddict.Core
@ -110,7 +111,7 @@ namespace OpenIddict.Core
// If no status was explicitly specified, assume that the token is valid. // If no status was explicitly specified, assume that the token is valid.
if (string.IsNullOrEmpty(await Store.GetStatusAsync(token, cancellationToken))) 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. // If a reference identifier was set, obfuscate it.
@ -1022,12 +1023,12 @@ namespace OpenIddict.Core
} }
var status = await Store.GetStatusAsync(token, cancellationToken); 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; return true;
} }
await Store.SetStatusAsync(token, OpenIddictConstants.Statuses.Redeemed, cancellationToken); await Store.SetStatusAsync(token, Statuses.Redeemed, cancellationToken);
try try
{ {
@ -1070,12 +1071,12 @@ namespace OpenIddict.Core
} }
var status = await Store.GetStatusAsync(token, cancellationToken); 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; return true;
} }
await Store.SetStatusAsync(token, OpenIddictConstants.Statuses.Rejected, cancellationToken); await Store.SetStatusAsync(token, Statuses.Rejected, cancellationToken);
try try
{ {
@ -1118,12 +1119,12 @@ namespace OpenIddict.Core
} }
var status = await Store.GetStatusAsync(token, cancellationToken); 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; return true;
} }
await Store.SetStatusAsync(token, OpenIddictConstants.Statuses.Revoked, cancellationToken); await Store.SetStatusAsync(token, Statuses.Revoked, cancellationToken);
try try
{ {
@ -1266,11 +1267,11 @@ namespace OpenIddict.Core
yield return new ValidationResult("The token type cannot be null or empty."); yield return new ValidationResult("The token type cannot be null or empty.");
} }
else if (!string.Equals(type, OpenIddictConstants.TokenUsages.AccessToken, StringComparison.OrdinalIgnoreCase) && else if (!string.Equals(type, TokenTypeHints.AccessToken, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.TokenUsages.AuthorizationCode, StringComparison.OrdinalIgnoreCase) && !string.Equals(type, TokenTypeHints.AuthorizationCode, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.TokenUsages.DeviceCode, StringComparison.OrdinalIgnoreCase) && !string.Equals(type, TokenTypeHints.DeviceCode, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.TokenUsages.RefreshToken, StringComparison.OrdinalIgnoreCase) && !string.Equals(type, TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.TokenUsages.UserCode, 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."); 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)) && if (string.IsNullOrEmpty(await Store.GetSubjectAsync(token, cancellationToken)) &&
!string.Equals(type, OpenIddictConstants.TokenUsages.DeviceCode, StringComparison.OrdinalIgnoreCase) && !string.Equals(type, TokenTypeHints.DeviceCode, StringComparison.OrdinalIgnoreCase) &&
!string.Equals(type, OpenIddictConstants.TokenUsages.UserCode, StringComparison.OrdinalIgnoreCase)) !string.Equals(type, TokenTypeHints.UserCode, StringComparison.OrdinalIgnoreCase))
{ {
yield return new ValidationResult("The subject cannot be null or empty."); yield return new ValidationResult("The subject cannot be null or empty.");
} }

2
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConstants.cs

@ -27,8 +27,6 @@ namespace OpenIddict.Server.DataProtection
public const string RefreshTokenLifetime = ".refresh_token_lifetime"; public const string RefreshTokenLifetime = ".refresh_token_lifetime";
public const string Resources = ".resources"; public const string Resources = ".resources";
public const string Scopes = ".scopes"; public const string Scopes = ".scopes";
public const string TokenId = ".token_id";
public const string TokenUsage = ".token_usage";
} }
public static class Purposes public static class Purposes

3
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs

@ -44,6 +44,7 @@ namespace OpenIddict.Server.DataProtection
.SetCreationDate(GetDateProperty(properties, Properties.Issued)) .SetCreationDate(GetDateProperty(properties, Properties.Issued))
.SetExpirationDate(GetDateProperty(properties, Properties.Expires)) .SetExpirationDate(GetDateProperty(properties, Properties.Expires))
.SetPresenters(GetArrayProperty(properties, Properties.Presenters)) .SetPresenters(GetArrayProperty(properties, Properties.Presenters))
.SetResources(GetArrayProperty(properties, Properties.Resources))
.SetScopes(GetArrayProperty(properties, Properties.Scopes)) .SetScopes(GetArrayProperty(properties, Properties.Scopes))
.SetClaim(Claims.Private.AccessTokenLifetime, GetProperty(properties, Properties.AccessTokenLifetime)) .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.Audiences, principal.GetAudiences());
SetArrayProperty(properties, Properties.Presenters, principal.GetPresenters()); SetArrayProperty(properties, Properties.Presenters, principal.GetPresenters());
SetArrayProperty(properties, Properties.Resources, principal.GetResources());
SetArrayProperty(properties, Properties.Scopes, principal.GetScopes()); SetArrayProperty(properties, Properties.Scopes, principal.GetScopes());
// Copy the principal and exclude the claim that were mapped to authentication properties. // 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.Presenters => false,
Claims.Private.RedirectUri => false, Claims.Private.RedirectUri => false,
Claims.Private.RefreshTokenLifetime => false, Claims.Private.RefreshTokenLifetime => false,
Claims.Private.Resources => false,
Claims.Private.Scopes => false, Claims.Private.Scopes => false,
Claims.Private.TokenId => false, Claims.Private.TokenId => false,

32
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. // If the token cannot be validated, don't return an error to allow another handle to validate it.
var principal = !string.IsNullOrEmpty(context.TokenType) ? var principal = !string.IsNullOrEmpty(context.TokenType) ?
ValidateToken(context.Token, context.TokenType) : ValidateToken(context.Token, context.TokenType) :
ValidateToken(context.Token, TokenUsages.AccessToken) ?? ValidateToken(context.Token, TokenTypeHints.AccessToken) ??
ValidateToken(context.Token, TokenUsages.RefreshToken) ?? ValidateToken(context.Token, TokenTypeHints.RefreshToken) ??
ValidateToken(context.Token, TokenUsages.AuthorizationCode) ?? ValidateToken(context.Token, TokenTypeHints.AuthorizationCode) ??
ValidateToken(context.Token, TokenUsages.DeviceCode) ?? ValidateToken(context.Token, TokenTypeHints.DeviceCode) ??
ValidateToken(context.Token, TokenUsages.UserCode); ValidateToken(context.Token, TokenTypeHints.UserCode);
if (principal == null) if (principal == null)
{ {
return default; return default;
@ -108,26 +108,26 @@ namespace OpenIddict.Server.DataProtection
// Create a Data Protection protector using the provider registered in the options. // Create a Data Protection protector using the provider registered in the options.
var protector = _options.CurrentValue.DataProtectionProvider.CreateProtector(type switch 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 }, => 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 }, => 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 }, => 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 }, => 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 }, => new[] { Handlers.Server, Formats.UserCode, Features.ReferenceTokens, Schemes.Server },
TokenUsages.AccessToken => new[] { Handlers.Server, Formats.AccessToken, Schemes.Server }, TokenTypeHints.AccessToken => new[] { Handlers.Server, Formats.AccessToken, Schemes.Server },
TokenUsages.AuthorizationCode => new[] { Handlers.Server, Formats.AuthorizationCode, Schemes.Server }, TokenTypeHints.AuthorizationCode => new[] { Handlers.Server, Formats.AuthorizationCode, Schemes.Server },
TokenUsages.DeviceCode => new[] { Handlers.Server, Formats.DeviceCode, Schemes.Server }, TokenTypeHints.DeviceCode => new[] { Handlers.Server, Formats.DeviceCode, Schemes.Server },
TokenUsages.RefreshToken => new[] { Handlers.Server, Formats.RefreshToken, Schemes.Server }, TokenTypeHints.RefreshToken => new[] { Handlers.Server, Formats.RefreshToken, Schemes.Server },
TokenUsages.UserCode => new[] { Handlers.Server, Formats.UserCode, Schemes.Server }, TokenTypeHints.UserCode => new[] { Handlers.Server, Formats.UserCode, Schemes.Server },
_ => throw new InvalidOperationException("The specified token type is not supported.") _ => 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 // 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. // 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) catch (Exception exception)

2
src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs

@ -1035,7 +1035,7 @@ namespace OpenIddict.Server
} }
context.TokenId = context.Principal.GetClaim(Claims.JwtId); 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.Subject = context.Principal.GetClaim(Claims.Subject);
context.IssuedAt = context.NotBefore = context.Principal.GetCreationDate(); context.IssuedAt = context.NotBefore = context.Principal.GetCreationDate();

69
src/OpenIddict.Server/OpenIddictServerHandlers.cs

@ -198,8 +198,8 @@ namespace OpenIddict.Server
var (token, type) = context.EndpointType switch var (token, type) = context.EndpointType switch
{ {
OpenIddictServerEndpointType.Authorization => (context.Request.IdTokenHint, TokenUsages.IdToken), OpenIddictServerEndpointType.Authorization => (context.Request.IdTokenHint, TokenTypeHints.IdToken),
OpenIddictServerEndpointType.Logout => (context.Request.IdTokenHint, TokenUsages.IdToken), OpenIddictServerEndpointType.Logout => (context.Request.IdTokenHint, TokenTypeHints.IdToken),
// Generic tokens received by the introspection and revocation can be of any type. // 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. // 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.Revocation => (context.Request.Token, null),
OpenIddictServerEndpointType.Token when context.Request.IsAuthorizationCodeGrantType() OpenIddictServerEndpointType.Token when context.Request.IsAuthorizationCodeGrantType()
=> (context.Request.Code, TokenUsages.AuthorizationCode), => (context.Request.Code, TokenTypeHints.AuthorizationCode),
OpenIddictServerEndpointType.Token when context.Request.IsDeviceCodeGrantType() OpenIddictServerEndpointType.Token when context.Request.IsDeviceCodeGrantType()
=> (context.Request.DeviceCode, TokenUsages.DeviceCode), => (context.Request.DeviceCode, TokenTypeHints.DeviceCode),
OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType() 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) _ => (null, null)
}; };
@ -279,7 +279,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context)); 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; return default;
} }
@ -445,13 +445,13 @@ namespace OpenIddict.Server
{ {
context.TokenType switch context.TokenType switch
{ {
TokenUsages.AccessToken => JsonWebTokenTypes.AccessToken, TokenTypeHints.AccessToken => JsonWebTokenTypes.AccessToken,
TokenUsages.IdToken => JsonWebTokenTypes.IdentityToken, TokenTypeHints.IdToken => JsonWebTokenTypes.IdentityToken,
TokenUsages.AuthorizationCode => JsonWebTokenTypes.Private.AuthorizationCode, TokenTypeHints.AuthorizationCode => JsonWebTokenTypes.Private.AuthorizationCode,
TokenUsages.DeviceCode => JsonWebTokenTypes.Private.DeviceCode, TokenTypeHints.DeviceCode => JsonWebTokenTypes.Private.DeviceCode,
TokenUsages.RefreshToken => JsonWebTokenTypes.Private.RefreshToken, TokenTypeHints.RefreshToken => JsonWebTokenTypes.Private.RefreshToken,
TokenUsages.UserCode => JsonWebTokenTypes.Private.UserCode, TokenTypeHints.UserCode => JsonWebTokenTypes.Private.UserCode,
_ => throw new InvalidOperationException("The token type is not supported.") _ => throw new InvalidOperationException("The token type is not supported.")
} }
@ -478,15 +478,15 @@ namespace OpenIddict.Server
context.Principal = new ClaimsPrincipal(result.ClaimsIdentity); context.Principal = new ClaimsPrincipal(result.ClaimsIdentity);
// Store the token type as a special private claim. // 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.AccessToken => TokenTypeHints.AccessToken,
JsonWebTokenTypes.IdentityToken => TokenUsages.IdToken, JsonWebTokenTypes.IdentityToken => TokenTypeHints.IdToken,
JsonWebTokenTypes.Private.AuthorizationCode => TokenUsages.AuthorizationCode, JsonWebTokenTypes.Private.AuthorizationCode => TokenTypeHints.AuthorizationCode,
JsonWebTokenTypes.Private.DeviceCode => TokenUsages.DeviceCode, JsonWebTokenTypes.Private.DeviceCode => TokenTypeHints.DeviceCode,
JsonWebTokenTypes.Private.RefreshToken => TokenUsages.RefreshToken, JsonWebTokenTypes.Private.RefreshToken => TokenTypeHints.RefreshToken,
JsonWebTokenTypes.Private.UserCode => TokenUsages.UserCode, JsonWebTokenTypes.Private.UserCode => TokenTypeHints.UserCode,
_ => throw new InvalidOperationException("The token type is not supported.") _ => throw new InvalidOperationException("The token type is not supported.")
}); });
@ -497,6 +497,19 @@ namespace OpenIddict.Server
context.Principal.SetDestinations(destinations); 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 " + context.Logger.LogTrace("The token '{Token}' was successfully validated and the following claims " +
"could be extracted: {Claims}.", context.Token, context.Principal.Claims); "could be extracted: {Claims}.", context.Token, context.Principal.Claims);
@ -563,7 +576,7 @@ namespace OpenIddict.Server
.SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token)) .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token))
.SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token)) .SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token))
.SetInternalTokenId(await _tokenManager.GetIdAsync(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)) .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token))
.SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token)) .SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token))
.SetInternalTokenId(await _tokenManager.GetIdAsync(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) async ValueTask TryRevokeAuthorizationChainAsync(string identifier)
{ {
@ -2791,7 +2804,7 @@ namespace OpenIddict.Server
ReferenceId = Base64UrlEncoder.Encode(data), ReferenceId = Base64UrlEncoder.Encode(data),
Status = Statuses.Valid, Status = Statuses.Valid,
Subject = context.AccessTokenPrincipal.GetClaim(Claims.Subject), Subject = context.AccessTokenPrincipal.GetClaim(Claims.Subject),
Type = TokenUsages.AccessToken Type = TokenTypeHints.AccessToken
}; };
// If the client application is known, associate it with the token. // If the client application is known, associate it with the token.
@ -2968,7 +2981,7 @@ namespace OpenIddict.Server
ReferenceId = Base64UrlEncoder.Encode(data), ReferenceId = Base64UrlEncoder.Encode(data),
Status = Statuses.Valid, Status = Statuses.Valid,
Subject = context.AuthorizationCodePrincipal.GetClaim(Claims.Subject), Subject = context.AuthorizationCodePrincipal.GetClaim(Claims.Subject),
Type = TokenUsages.AuthorizationCode Type = TokenTypeHints.AuthorizationCode
}; };
// If the client application is known, associate it with the token. // If the client application is known, associate it with the token.
@ -3150,7 +3163,7 @@ namespace OpenIddict.Server
ReferenceId = Base64UrlEncoder.Encode(data), ReferenceId = Base64UrlEncoder.Encode(data),
Status = Statuses.Inactive, Status = Statuses.Inactive,
Subject = null, // Device codes are not bound to a user, which is not known until the user code is populated. 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. // If the client application is known, associate it with the token.
@ -3423,7 +3436,7 @@ namespace OpenIddict.Server
ReferenceId = Base64UrlEncoder.Encode(data), ReferenceId = Base64UrlEncoder.Encode(data),
Status = Statuses.Valid, Status = Statuses.Valid,
Subject = context.RefreshTokenPrincipal.GetClaim(Claims.Subject), Subject = context.RefreshTokenPrincipal.GetClaim(Claims.Subject),
Type = TokenUsages.RefreshToken Type = TokenTypeHints.RefreshToken
}; };
// If the client application is known, associate it with the token. // If the client application is known, associate it with the token.
@ -3641,7 +3654,7 @@ namespace OpenIddict.Server
ReferenceId = builder.ToString(), ReferenceId = builder.ToString(),
Status = Statuses.Valid, Status = Statuses.Valid,
Subject = null, // User codes are not bound to a user until authorization is granted. 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. // If the client application is known, associate it with the token.

2
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConstants.cs

@ -27,8 +27,6 @@ namespace OpenIddict.Validation.DataProtection
public const string RefreshTokenLifetime = ".refresh_token_lifetime"; public const string RefreshTokenLifetime = ".refresh_token_lifetime";
public const string Resources = ".resources"; public const string Resources = ".resources";
public const string Scopes = ".scopes"; public const string Scopes = ".scopes";
public const string TokenId = ".token_id";
public const string TokenUsage = ".token_usage";
} }
public static class Purposes public static class Purposes

3
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs

@ -10,8 +10,8 @@ using System.Collections.Immutable;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations;
using System.Text.Json; using System.Text.Json;
using JetBrains.Annotations;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
using Properties = OpenIddict.Validation.DataProtection.OpenIddictValidationDataProtectionConstants.Properties; using Properties = OpenIddict.Validation.DataProtection.OpenIddictValidationDataProtectionConstants.Properties;
@ -42,6 +42,7 @@ namespace OpenIddict.Validation.DataProtection
.SetCreationDate(GetDateProperty(properties, Properties.Issued)) .SetCreationDate(GetDateProperty(properties, Properties.Issued))
.SetExpirationDate(GetDateProperty(properties, Properties.Expires)) .SetExpirationDate(GetDateProperty(properties, Properties.Expires))
.SetPresenters(GetArrayProperty(properties, Properties.Presenters)) .SetPresenters(GetArrayProperty(properties, Properties.Presenters))
.SetResources(GetArrayProperty(properties, Properties.Resources))
.SetScopes(GetArrayProperty(properties, Properties.Scopes)) .SetScopes(GetArrayProperty(properties, Properties.Scopes))
.SetClaim(Claims.Private.AccessTokenLifetime, GetProperty(properties, Properties.AccessTokenLifetime)) .SetClaim(Claims.Private.AccessTokenLifetime, GetProperty(properties, Properties.AccessTokenLifetime))

2
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 // 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. // 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 " + 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); "claims could be extracted: {Claims}.", context.Token, context.Principal.Claims);

16
src/OpenIddict.Validation/OpenIddictValidationHandlers.cs

@ -130,7 +130,7 @@ namespace OpenIddict.Validation
} }
var type = await _tokenManager.GetTypeAsync(token); var type = await _tokenManager.GetTypeAsync(token);
if (!string.Equals(type, TokenUsages.AccessToken, StringComparison.OrdinalIgnoreCase)) if (!string.Equals(type, TokenTypeHints.AccessToken, StringComparison.OrdinalIgnoreCase))
{ {
context.Reject( context.Reject(
error: Errors.InvalidToken, error: Errors.InvalidToken,
@ -221,7 +221,17 @@ namespace OpenIddict.Validation
// Attach the principal extracted from the token to the parent event context. // Attach the principal extracted from the token to the parent event context.
context.Principal = new ClaimsPrincipal(result.ClaimsIdentity); 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 " + 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); "claims could be extracted: {Claims}.", context.Token, context.Principal.Claims);
@ -286,7 +296,7 @@ namespace OpenIddict.Validation
.SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token)) .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token))
.SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token)) .SetInternalAuthorizationId(await _tokenManager.GetAuthorizationIdAsync(token))
.SetInternalTokenId(await _tokenManager.GetIdAsync(token)) .SetInternalTokenId(await _tokenManager.GetIdAsync(token))
.SetClaim(Claims.Private.TokenUsage, await _tokenManager.GetTypeAsync(token)); .SetClaim(Claims.Private.TokenType, await _tokenManager.GetTypeAsync(token));
} }
} }

112
test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs

@ -1906,13 +1906,13 @@ namespace OpenIddict.Abstractions.Tests.Primitives
} }
[Fact] [Fact]
public void GetTokenUsage_ThrowsAnExceptionForNullPrincipal() public void GetTokenType_ThrowsAnExceptionForNullPrincipal()
{ {
// Arrange // Arrange
var principal = (ClaimsPrincipal) null; var principal = (ClaimsPrincipal) null;
// Act and assert // Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => principal.GetTokenUsage()); var exception = Assert.Throws<ArgumentNullException>(() => principal.GetTokenType());
Assert.Equal("principal", exception.ParamName); Assert.Equal("principal", exception.ParamName);
} }
@ -1920,16 +1920,16 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null)] [InlineData(null)]
[InlineData("access_token")] [InlineData("access_token")]
public void GetTokenUsage_ReturnsExpectedResult(string usage) public void GetTokenType_ReturnsExpectedResult(string type)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
principal.SetClaim(Claims.Private.TokenUsage, usage); principal.SetClaim(Claims.Private.TokenType, type);
// Act and assert // Act and assert
Assert.Equal(usage, principal.GetTokenUsage()); Assert.Equal(type, principal.GetTokenType());
} }
[Fact] [Fact]
@ -2203,19 +2203,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null, false)] [InlineData(null, false)]
[InlineData("unknown", false)] [InlineData("unknown", false)]
[InlineData(TokenUsages.AccessToken, true)] [InlineData(TokenTypeHints.AccessToken, true)]
[InlineData(TokenUsages.AuthorizationCode, false)] [InlineData(TokenTypeHints.AuthorizationCode, false)]
[InlineData(TokenUsages.DeviceCode, false)] [InlineData(TokenTypeHints.DeviceCode, false)]
[InlineData(TokenUsages.IdToken, false)] [InlineData(TokenTypeHints.IdToken, false)]
[InlineData(TokenUsages.RefreshToken, false)] [InlineData(TokenTypeHints.RefreshToken, false)]
[InlineData(TokenUsages.UserCode, false)] [InlineData(TokenTypeHints.UserCode, false)]
public void IsAccessToken_ReturnsExpectedResult(string usage, bool result) public void IsAccessToken_ReturnsExpectedResult(string type, bool result)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
principal.SetClaim(Claims.Private.TokenUsage, usage); principal.SetClaim(Claims.Private.TokenType, type);
// Act and assert // Act and assert
Assert.Equal(result, principal.IsAccessToken()); Assert.Equal(result, principal.IsAccessToken());
@ -2236,19 +2236,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null, false)] [InlineData(null, false)]
[InlineData("unknown", false)] [InlineData("unknown", false)]
[InlineData(TokenUsages.AccessToken, false)] [InlineData(TokenTypeHints.AccessToken, false)]
[InlineData(TokenUsages.AuthorizationCode, true)] [InlineData(TokenTypeHints.AuthorizationCode, true)]
[InlineData(TokenUsages.DeviceCode, false)] [InlineData(TokenTypeHints.DeviceCode, false)]
[InlineData(TokenUsages.IdToken, false)] [InlineData(TokenTypeHints.IdToken, false)]
[InlineData(TokenUsages.RefreshToken, false)] [InlineData(TokenTypeHints.RefreshToken, false)]
[InlineData(TokenUsages.UserCode, false)] [InlineData(TokenTypeHints.UserCode, false)]
public void IsAuthorizationCode_ReturnsExpectedResult(string usage, bool result) public void IsAuthorizationCode_ReturnsExpectedResult(string type, bool result)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
principal.SetClaim(Claims.Private.TokenUsage, usage); principal.SetClaim(Claims.Private.TokenType, type);
// Act and assert // Act and assert
Assert.Equal(result, principal.IsAuthorizationCode()); Assert.Equal(result, principal.IsAuthorizationCode());
@ -2269,19 +2269,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null, false)] [InlineData(null, false)]
[InlineData("unknown", false)] [InlineData("unknown", false)]
[InlineData(TokenUsages.AccessToken, false)] [InlineData(TokenTypeHints.AccessToken, false)]
[InlineData(TokenUsages.AuthorizationCode, false)] [InlineData(TokenTypeHints.AuthorizationCode, false)]
[InlineData(TokenUsages.DeviceCode, true)] [InlineData(TokenTypeHints.DeviceCode, true)]
[InlineData(TokenUsages.IdToken, false)] [InlineData(TokenTypeHints.IdToken, false)]
[InlineData(TokenUsages.RefreshToken, false)] [InlineData(TokenTypeHints.RefreshToken, false)]
[InlineData(TokenUsages.UserCode, false)] [InlineData(TokenTypeHints.UserCode, false)]
public void IsDeviceCode_ReturnsExpectedResult(string usage, bool result) public void IsDeviceCode_ReturnsExpectedResult(string type, bool result)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
principal.SetClaim(Claims.Private.TokenUsage, usage); principal.SetClaim(Claims.Private.TokenType, type);
// Act and assert // Act and assert
Assert.Equal(result, principal.IsDeviceCode()); Assert.Equal(result, principal.IsDeviceCode());
@ -2302,19 +2302,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null, false)] [InlineData(null, false)]
[InlineData("unknown", false)] [InlineData("unknown", false)]
[InlineData(TokenUsages.AccessToken, false)] [InlineData(TokenTypeHints.AccessToken, false)]
[InlineData(TokenUsages.AuthorizationCode, false)] [InlineData(TokenTypeHints.AuthorizationCode, false)]
[InlineData(TokenUsages.DeviceCode, false)] [InlineData(TokenTypeHints.DeviceCode, false)]
[InlineData(TokenUsages.IdToken, true)] [InlineData(TokenTypeHints.IdToken, true)]
[InlineData(TokenUsages.RefreshToken, false)] [InlineData(TokenTypeHints.RefreshToken, false)]
[InlineData(TokenUsages.UserCode, false)] [InlineData(TokenTypeHints.UserCode, false)]
public void IsIdentityToken_ReturnsExpectedResult(string usage, bool result) public void IsIdentityToken_ReturnsExpectedResult(string type, bool result)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
principal.SetClaim(Claims.Private.TokenUsage, usage); principal.SetClaim(Claims.Private.TokenType, type);
// Act and assert // Act and assert
Assert.Equal(result, principal.IsIdentityToken()); Assert.Equal(result, principal.IsIdentityToken());
@ -2335,17 +2335,17 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null, false)] [InlineData(null, false)]
[InlineData("unknown", false)] [InlineData("unknown", false)]
[InlineData(TokenUsages.AccessToken, false)] [InlineData(TokenTypeHints.AccessToken, false)]
[InlineData(TokenUsages.AuthorizationCode, false)] [InlineData(TokenTypeHints.AuthorizationCode, false)]
[InlineData(TokenUsages.IdToken, false)] [InlineData(TokenTypeHints.IdToken, false)]
[InlineData(TokenUsages.RefreshToken, true)] [InlineData(TokenTypeHints.RefreshToken, true)]
public void IsRefreshToken_ReturnsExpectedResult(string usage, bool result) public void IsRefreshToken_ReturnsExpectedResult(string type, bool result)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
principal.SetClaim(Claims.Private.TokenUsage, usage); principal.SetClaim(Claims.Private.TokenType, type);
// Act and assert // Act and assert
Assert.Equal(result, principal.IsRefreshToken()); Assert.Equal(result, principal.IsRefreshToken());
@ -2366,19 +2366,19 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null, false)] [InlineData(null, false)]
[InlineData("unknown", false)] [InlineData("unknown", false)]
[InlineData(TokenUsages.AccessToken, false)] [InlineData(TokenTypeHints.AccessToken, false)]
[InlineData(TokenUsages.AuthorizationCode, false)] [InlineData(TokenTypeHints.AuthorizationCode, false)]
[InlineData(TokenUsages.DeviceCode, false)] [InlineData(TokenTypeHints.DeviceCode, false)]
[InlineData(TokenUsages.IdToken, false)] [InlineData(TokenTypeHints.IdToken, false)]
[InlineData(TokenUsages.RefreshToken, false)] [InlineData(TokenTypeHints.RefreshToken, false)]
[InlineData(TokenUsages.UserCode, true)] [InlineData(TokenTypeHints.UserCode, true)]
public void IsUserCode_ReturnsExpectedResult(string usage, bool result) public void IsUserCode_ReturnsExpectedResult(string type, bool result)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
principal.SetClaim(Claims.Private.TokenUsage, usage); principal.SetClaim(Claims.Private.TokenType, type);
// Act and assert // Act and assert
Assert.Equal(result, principal.IsUserCode()); Assert.Equal(result, principal.IsUserCode());
@ -2973,13 +2973,13 @@ namespace OpenIddict.Abstractions.Tests.Primitives
} }
[Fact] [Fact]
public void SetTokenUsage_ThrowsAnExceptionForNullPrincipal() public void SetTokenType_ThrowsAnExceptionForNullPrincipal()
{ {
// Arrange // Arrange
var principal = (ClaimsPrincipal) null; var principal = (ClaimsPrincipal) null;
// Act and assert // Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => principal.SetTokenUsage(null)); var exception = Assert.Throws<ArgumentNullException>(() => principal.SetTokenType(null));
Assert.Equal("principal", exception.ParamName); Assert.Equal("principal", exception.ParamName);
} }
@ -2987,17 +2987,17 @@ namespace OpenIddict.Abstractions.Tests.Primitives
[Theory] [Theory]
[InlineData(null)] [InlineData(null)]
[InlineData("access_token")] [InlineData("access_token")]
public void SetTokenUsage_AddsUsage(string usage) public void SetTokenType_AddsType(string type)
{ {
// Arrange // Arrange
var identity = new ClaimsIdentity(); var identity = new ClaimsIdentity();
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
// Act // Act
principal.SetTokenUsage(usage); principal.SetTokenType(type);
// Assert // Assert
Assert.Equal(usage, principal.GetClaim(Claims.Private.TokenUsage)); Assert.Equal(type, principal.GetClaim(Claims.Private.TokenType));
} }
private TimeSpan? ParseLifeTime(string lifetime) private TimeSpan? ParseLifeTime(string lifetime)

64
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs

@ -398,7 +398,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetExpirationDate(DateTimeOffset.UtcNow - TimeSpan.FromDays(1)); .SetExpirationDate(DateTimeOffset.UtcNow - TimeSpan.FromDays(1));
@ -436,7 +436,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetExpirationDate(DateTimeOffset.UtcNow - TimeSpan.FromDays(1)); .SetExpirationDate(DateTimeOffset.UtcNow - TimeSpan.FromDays(1));
@ -473,7 +473,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters(Enumerable.Empty<string>()); .SetPresenters(Enumerable.Empty<string>());
@ -512,7 +512,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Contoso"); .SetPresenters("Contoso");
@ -550,7 +550,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Contoso"); .SetPresenters("Contoso");
@ -588,7 +588,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -628,7 +628,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -669,7 +669,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -712,7 +712,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -755,7 +755,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetClaim(Claims.Subject, "Bob le Magnifique") .SetClaim(Claims.Subject, "Bob le Magnifique")
@ -796,7 +796,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -836,7 +836,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -876,7 +876,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetScopes(Enumerable.Empty<string>()); .SetScopes(Enumerable.Empty<string>());
@ -914,7 +914,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetScopes("profile", "email"); .SetScopes("profile", "email");
@ -1552,7 +1552,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -1604,7 +1604,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103"); .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103");
@ -1648,7 +1648,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetInternalTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); .SetInternalTokenId("3E228451-1555-46F7-A471-951EFBA23A56");
@ -1706,7 +1706,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -1760,7 +1760,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -1828,7 +1828,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103"); .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103");
@ -1876,7 +1876,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -1959,7 +1959,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103")
@ -2049,7 +2049,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -2136,7 +2136,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -2198,7 +2198,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -2271,7 +2271,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -2319,7 +2319,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -2404,7 +2404,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103")
@ -2471,7 +2471,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -2556,7 +2556,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token);
Assert.Equal(TokenUsages.AuthorizationCode, context.TokenType); Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetPresenters("Fabrikam") .SetPresenters("Fabrikam")
@ -2637,7 +2637,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103")
@ -2708,7 +2708,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("8xLOxBtZp8", context.Token); Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenUsages.RefreshToken, context.TokenType); Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") .SetInternalTokenId("60FFF7EA-F98E-437B-937E-5073CC313103")

6
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs

@ -191,7 +191,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("id_token", context.Token); 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")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetClaim(Claims.Subject, "Bob le Magnifique"); .SetClaim(Claims.Subject, "Bob le Magnifique");
@ -295,7 +295,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("authorization_code", context.Token); 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")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetClaim(Claims.Subject, "Bob le Magnifique") .SetClaim(Claims.Subject, "Bob le Magnifique")
@ -400,7 +400,7 @@ namespace OpenIddict.Server.FunctionalTests
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.Equal("refresh_token", context.Token); 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")) context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetClaim(Claims.Subject, "Bob le Magnifique"); .SetClaim(Claims.Subject, "Bob le Magnifique");

Loading…
Cancel
Save