diff --git a/shared/OpenIddict.Extensions/Helpers/OpenIddictHelpers.cs b/shared/OpenIddict.Extensions/Helpers/OpenIddictHelpers.cs
index 65624a72..b90a5b46 100644
--- a/shared/OpenIddict.Extensions/Helpers/OpenIddictHelpers.cs
+++ b/shared/OpenIddict.Extensions/Helpers/OpenIddictHelpers.cs
@@ -16,7 +16,7 @@ namespace OpenIddict.Extensions
/// The type to introspect.
/// The generic type definition.
/// A instance if the base type was found, null otherwise.
- public static Type FindGenericBaseType(Type type, Type definition)
+ public static Type? FindGenericBaseType(Type type, Type definition)
=> FindGenericBaseTypes(type, definition).FirstOrDefault();
///
diff --git a/src/OpenIddict.Abstractions/OpenIddictResources.resx b/src/OpenIddict.Abstractions/OpenIddictResources.resx
index 8e0bb501..755354b0 100644
--- a/src/OpenIddict.Abstractions/OpenIddictResources.resx
+++ b/src/OpenIddict.Abstractions/OpenIddictResources.resx
@@ -152,7 +152,7 @@ When implementing custom token deserialization, a 'oi_tkn_typ' claim containing
A sign-in response cannot be returned from this endpoint.
- The specified principal doesn't contain any claims-based identity.
+ The specified principal is null or doesn't contain a claims-based identity.
Make sure that 'ClaimsPrincipal.Identity' is not null.
@@ -184,7 +184,7 @@ Alternatively, you can disable the built-in database-based server features by en
An unknown error occurred while creating a token entry.
- A token entry cannot be created from a null principal.
+ A token entry cannot be created from a null principal or from a principal containing a null or invalid identity.
The token entry cannot be found in the database.
@@ -1113,6 +1113,9 @@ To register the OpenIddict core services, reference the 'OpenIddict.Core' packag
Endpoint addresses must be unique across endpoints.
+
+ The specified principal doesn't contain a valid claims-based identity.
+
The security token is missing.
@@ -1483,7 +1486,7 @@ To register the OpenIddict core services, reference the 'OpenIddict.Core' packag
ECDsa.ExportParameters() shouldn't return an unnamed curve.
- The principal shouldn't be null at this point.
+ The principal and its attached identity shouldn't be null at this point.
The response shouldn't be null at this point.
diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs
index db688500..40136ed0 100644
--- a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs
+++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs
@@ -525,7 +525,7 @@ namespace OpenIddict.Abstractions
foreach (var element in document.RootElement.EnumerateArray())
{
var value = element.GetString();
- if (builder.Contains(value, StringComparer.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(value) || builder.Contains(value, StringComparer.OrdinalIgnoreCase))
{
continue;
}
@@ -1061,6 +1061,11 @@ namespace OpenIddict.Abstractions
throw new ArgumentNullException(nameof(principal));
}
+ if (principal.Identity is not ClaimsIdentity identity)
+ {
+ throw new ArgumentException(SR.GetResourceString(SR.ID0286), nameof(principal));
+ }
+
if (string.IsNullOrEmpty(type))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0184), nameof(type));
@@ -1070,7 +1075,7 @@ namespace OpenIddict.Abstractions
if (!string.IsNullOrEmpty(value))
{
- ((ClaimsIdentity) principal.Identity).AddClaim(type, value);
+ identity.AddClaim(type, value);
}
return principal;
@@ -1119,6 +1124,11 @@ namespace OpenIddict.Abstractions
throw new ArgumentNullException(nameof(principal));
}
+ if (principal.Identity is not ClaimsIdentity identity)
+ {
+ throw new ArgumentException(SR.GetResourceString(SR.ID0286), nameof(principal));
+ }
+
if (string.IsNullOrEmpty(type))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0184), nameof(type));
@@ -1128,7 +1138,7 @@ namespace OpenIddict.Abstractions
foreach (var value in values.Distinct(StringComparer.Ordinal))
{
- ((ClaimsIdentity) principal.Identity).AddClaim(type, value);
+ identity.AddClaim(type, value);
}
return principal;
diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs
index 020d84bd..fcdeabc1 100644
--- a/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs
+++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs
@@ -258,7 +258,7 @@ namespace OpenIddict.Abstractions
return value.GetInt64().GetHashCode();
case JsonValueKind.String:
- return value.GetString().GetHashCode();
+ return value.GetString()!.GetHashCode();
case JsonValueKind.Array:
{
@@ -420,12 +420,15 @@ namespace OpenIddict.Abstractions
{
null => string.Empty,
- string value => value,
+ bool value => value ? bool.TrueString : bool.FalseString,
+ long value => value.ToString(CultureInfo.InvariantCulture),
+
+ string value => value,
string?[] value => string.Join(", ", value),
JsonElement value => value.ToString(),
- var value => value.ToString()
+ _ => throw new InvalidOperationException(SR.GetResourceString(SR.ID0194))
};
///
@@ -799,7 +802,7 @@ namespace OpenIddict.Abstractions
static string?[]? CreateArray(JsonElement value)
{
- var array = new string[value.GetArrayLength()];
+ var array = new string?[value.GetArrayLength()];
using var enumerator = value.EnumerateArray();
for (var index = 0; enumerator.MoveNext(); index++)
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
index 5265b957..7a8eda0a 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
@@ -404,7 +404,13 @@ namespace OpenIddict.EntityFramework
foreach (var property in document.RootElement.EnumerateObject())
{
- builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
+ var value = property.Value.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder[CultureInfo.GetCultureInfo(property.Name)] = value;
}
return builder.ToImmutable();
@@ -450,7 +456,13 @@ namespace OpenIddict.EntityFramework
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
@@ -485,7 +497,13 @@ namespace OpenIddict.EntityFramework
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
@@ -555,7 +573,13 @@ namespace OpenIddict.EntityFramework
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
@@ -590,7 +614,13 @@ namespace OpenIddict.EntityFramework
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
index 77b7ad1e..e4e32187 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
@@ -500,7 +500,13 @@ namespace OpenIddict.EntityFramework
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs
index 025502af..11fb520e 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs
@@ -265,7 +265,13 @@ namespace OpenIddict.EntityFramework
foreach (var property in document.RootElement.EnumerateObject())
{
- builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
+ var value = property.Value.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder[CultureInfo.GetCultureInfo(property.Name)] = value;
}
return builder.ToImmutable();
@@ -311,7 +317,13 @@ namespace OpenIddict.EntityFramework
foreach (var property in document.RootElement.EnumerateObject())
{
- builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
+ var value = property.Value.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder[CultureInfo.GetCultureInfo(property.Name)] = value;
}
return builder.ToImmutable();
@@ -403,7 +415,13 @@ namespace OpenIddict.EntityFramework
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
index be6e82ca..2ce6182e 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
@@ -448,7 +448,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var property in document.RootElement.EnumerateObject())
{
- builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
+ var value = property.Value.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder[CultureInfo.GetCultureInfo(property.Name)] = value;
}
return builder.ToImmutable();
@@ -494,7 +500,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
@@ -529,7 +541,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
@@ -599,7 +617,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
@@ -634,7 +658,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
index 3b25725e..643053c1 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
@@ -568,7 +568,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
index 57513223..df777826 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
@@ -281,7 +281,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var property in document.RootElement.EnumerateObject())
{
- builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
+ var value = property.Value.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder[CultureInfo.GetCultureInfo(property.Name)] = value;
}
return builder.ToImmutable();
@@ -327,7 +333,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var property in document.RootElement.EnumerateObject())
{
- builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
+ var value = property.Value.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder[CultureInfo.GetCultureInfo(property.Name)] = value;
}
return builder.ToImmutable();
@@ -419,7 +431,13 @@ namespace OpenIddict.EntityFrameworkCore
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var value = element.GetString();
+ if (string.IsNullOrEmpty(value))
+ {
+ continue;
+ }
+
+ builder.Add(value);
}
return builder.ToImmutable();
diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs
index c9c76c4d..2d214c47 100644
--- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs
+++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs
@@ -155,7 +155,7 @@ namespace OpenIddict.Server.AspNetCore
else
{
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.Principal.GetTokenType()), SR.GetResourceString(SR.ID4009));
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID4010));
diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs
index 9113ce8c..2f02cb8c 100644
--- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs
+++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs
@@ -189,7 +189,13 @@ namespace OpenIddict.Server.DataProtection
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var item = element.GetString();
+ if (string.IsNullOrEmpty(item))
+ {
+ continue;
+ }
+
+ builder.Add(item);
}
return builder.ToImmutable();
@@ -264,7 +270,7 @@ namespace OpenIddict.Server.DataProtection
Claims.Private.TokenId or
Claims.Private.UserCodeLifetime));
- Write(writer, principal.Identity.AuthenticationType, principal, properties);
+ Write(writer, principal.Identity?.AuthenticationType, principal, properties);
writer.Flush();
// Note: the following local methods closely matches the logic used by ASP.NET Core's
diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs
index 4eedbb83..ca5bc475 100644
--- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs
+++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs
@@ -167,7 +167,7 @@ namespace OpenIddict.Server.Owin
else
{
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.Principal.GetTokenType()), SR.GetResourceString(SR.ID4009));
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID4010));
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs
index 649aabd3..dea942c3 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs
@@ -371,7 +371,7 @@ namespace OpenIddict.Server
return default;
- static Uri? GetEndpointAbsoluteUri(Uri? issuer, Uri endpoint)
+ static Uri? GetEndpointAbsoluteUri(Uri? issuer, Uri? endpoint)
{
// If the endpoint is disabled (i.e a null address is specified), return null.
if (endpoint is null)
@@ -1248,8 +1248,8 @@ namespace OpenIddict.Server
// Warning: on .NET Framework 4.x and .NET Core 2.1, exported ECParameters generally have
// a null OID value attached. To work around this limitation, both the friendly names and
// the raw OID value are compared to determine whether the curve is of the specified type.
- string.Equals(parameters.Curve.Oid.Value, curve.Oid.Value, StringComparison.Ordinal) ||
- string.Equals(parameters.Curve.Oid.FriendlyName, curve.Oid.FriendlyName, StringComparison.Ordinal);
+ string.Equals(parameters.Curve.Oid?.Value, curve.Oid?.Value, StringComparison.Ordinal) ||
+ string.Equals(parameters.Curve.Oid?.FriendlyName, curve.Oid?.FriendlyName, StringComparison.Ordinal);
#endif
static byte[] GetCertificateHash(X509Certificate2 certificate, HashAlgorithmName algorithm)
@@ -1257,7 +1257,7 @@ namespace OpenIddict.Server
#if SUPPORTS_CERTIFICATE_HASHING_WITH_SPECIFIED_ALGORITHM
return certificate.GetCertHash(algorithm);
#else
- using var hash = CryptoConfig.CreateFromName(algorithm.Name) as HashAlgorithm;
+ using var hash = CryptoConfig.CreateFromName(algorithm.Name!) as HashAlgorithm;
if (hash is null || hash is KeyedHashAlgorithm)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0217));
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
index 70177f76..e29a4341 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
@@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
+using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
@@ -1331,7 +1332,7 @@ namespace OpenIddict.Server
return default;
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
var presenters = context.Principal.GetPresenters();
if (presenters.IsDefaultOrEmpty)
@@ -1415,7 +1416,7 @@ namespace OpenIddict.Server
return default;
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Validate the redirect_uri sent by the client application as part of this token request.
// Note: for pure OAuth 2.0 requests, redirect_uri is only mandatory if the authorization request
@@ -1484,7 +1485,7 @@ namespace OpenIddict.Server
return default;
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Note: the ValidateProofKeyForCodeExchangeRequirement handler (invoked earlier) ensures
// a code_verifier is specified if the proof key for code exchange requirement was enforced
@@ -1605,7 +1606,7 @@ namespace OpenIddict.Server
return default;
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// When an explicit scope parameter has been included in the token request
// but was missing from the initial request, the request MUST be rejected.
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
index c6696e44..ea19f4e5 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
@@ -742,7 +742,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) &&
!context.Principal.HasTokenType(TokenTypeHints.RefreshToken))
@@ -789,7 +789,7 @@ namespace OpenIddict.Server
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// When the introspected token is an access token, the caller must be listed either as a presenter
// (i.e the party the token was issued to) or as an audience (i.e a resource server/API).
@@ -885,7 +885,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
context.TokenId = context.Principal.GetClaim(Claims.JwtId);
context.TokenUsage = context.Principal.GetTokenType();
@@ -945,7 +945,7 @@ namespace OpenIddict.Server
}
Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), SR.FormatID4000(Parameters.ClientId));
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Don't return application-specific claims if the token is not an access token.
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken))
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
index 5fea8966..0b8614fa 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
+using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
@@ -684,7 +685,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) &&
!context.Principal.HasTokenType(TokenTypeHints.RefreshToken))
@@ -731,7 +732,7 @@ namespace OpenIddict.Server
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// When the revoked token is an access token, the caller must be listed either as a presenter
// (i.e the party the token was issued to) or as an audience (i.e a resource server/API).
@@ -836,7 +837,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Extract the token identifier from the authentication principal.
var identifier = context.Principal.GetTokenId();
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs
index 1524fe5d..5b18ecd1 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs
@@ -8,6 +8,7 @@ using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
+using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
@@ -461,7 +462,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Note: when receiving an access token, its audiences list cannot be used for the "aud" claim
// as the client application is not the intented audience but only an authorized presenter.
@@ -495,7 +496,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
context.Subject = context.Principal.GetClaim(Claims.Subject);
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
index 99c34402..53f1e462 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
@@ -823,7 +823,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Extract the token identifier from the authentication principal.
// If no token identifier can be found, this indicates that the token
@@ -1030,7 +1030,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
var identifier = context.Principal.GetAuthorizationId();
if (string.IsNullOrEmpty(identifier))
@@ -1089,7 +1089,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Don't validate the lifetime of id_tokens used as id_token_hints.
if (context.EndpointType is OpenIddictServerEndpointType.Authorization or OpenIddictServerEndpointType.Logout)
@@ -1355,8 +1355,6 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
-
if (context.EndpointType is not (OpenIddictServerEndpointType.Authorization or
OpenIddictServerEndpointType.Device or
OpenIddictServerEndpointType.Token or
@@ -1365,7 +1363,7 @@ namespace OpenIddict.Server
throw new InvalidOperationException(SR.GetResourceString(SR.ID0010));
}
- if (context.Principal.Identity is null)
+ if (context.Principal is not { Identity: ClaimsIdentity })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0011));
}
@@ -1384,18 +1382,19 @@ namespace OpenIddict.Server
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0013));
}
-
- return default;
}
- if (!context.Principal.Identity.IsAuthenticated)
+ else
{
- throw new InvalidOperationException(SR.GetResourceString(SR.ID0014));
- }
+ if (!context.Principal.Identity.IsAuthenticated)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0014));
+ }
- if (string.IsNullOrEmpty(context.Principal.GetClaim(Claims.Subject)))
- {
- throw new InvalidOperationException(SR.GetResourceString(SR.ID0015));
+ if (string.IsNullOrEmpty(context.Principal.GetClaim(Claims.Subject)))
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0015));
+ }
}
return default;
@@ -1425,7 +1424,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
switch (context.EndpointType)
{
@@ -1497,7 +1496,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Always include the "openid" scope when the developer doesn't explicitly call SetScopes.
// Note: the application is allowed to specify a different "scopes": in this case,
@@ -1534,7 +1533,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Add the validated client_id to the list of authorized presenters,
// unless the presenters were explicitly set by the developer.
@@ -1570,7 +1569,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// When a "resources" property cannot be found in the ticket, infer it from the "audiences" property.
if (context.Principal.HasAudience() && !context.Principal.HasResource())
@@ -1609,7 +1608,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
(context.GenerateAccessToken, context.IncludeAccessToken) = context.EndpointType switch
{
@@ -1723,7 +1722,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// If no authorization code, device code or refresh token is returned, don't create an authorization.
if (!context.GenerateAuthorizationCode && !context.GenerateDeviceCode && !context.GenerateRefreshToken)
@@ -1809,7 +1808,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Create a new principal containing only the filtered claims.
// Actors identities are also filtered (delegation scenarios).
@@ -1927,7 +1926,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Create a new principal containing only the filtered claims.
// Actors identities are also filtered (delegation scenarios).
@@ -2012,7 +2011,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Note: a device code principal is produced when a device code is included in the response or when a
// device code entry is replaced when processing a sign-in response sent to the verification endpoint.
@@ -2092,7 +2091,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Create a new principal containing only the filtered claims.
// Actors identities are also filtered (delegation scenarios).
@@ -2176,7 +2175,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Replace the principal by a new one containing only the filtered claims.
// Actors identities are also filtered (delegation scenarios).
@@ -2289,7 +2288,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Create a new principal containing only the filtered claims.
// Actors identities are also filtered (delegation scenarios).
@@ -2379,7 +2378,7 @@ namespace OpenIddict.Server
default: return;
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// Extract the token identifier from the authentication principal.
// If no token identifier can be found, this indicates that the token has no backing database entry.
@@ -2526,7 +2525,7 @@ namespace OpenIddict.Server
Claims.Private.Scope or
Claims.Private.TokenType));
- if (principal is null)
+ if (principal is null or { Identity: not ClaimsIdentity })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0020));
}
@@ -2785,7 +2784,7 @@ namespace OpenIddict.Server
Claims.Private.ExpirationDate or
Claims.Private.TokenType));
- if (principal is null)
+ if (principal is null or { Identity: not ClaimsIdentity })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0022));
}
@@ -3031,7 +3030,7 @@ namespace OpenIddict.Server
Claims.Private.ExpirationDate or
Claims.Private.TokenType));
- if (principal is null)
+ if (principal is null or { Identity: not ClaimsIdentity })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0022));
}
@@ -3197,7 +3196,7 @@ namespace OpenIddict.Server
return;
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
var principal = context.DeviceCodePrincipal;
if (principal is null)
@@ -3361,7 +3360,7 @@ namespace OpenIddict.Server
Claims.Private.ExpirationDate or
Claims.Private.TokenType));
- if (principal is null)
+ if (principal is null or { Identity: not ClaimsIdentity })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0022));
}
@@ -3644,7 +3643,7 @@ namespace OpenIddict.Server
Claims.Private.ExpirationDate or
Claims.Private.TokenType));
- if (principal is null)
+ if (principal is null or { Identity: not ClaimsIdentity })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0022));
}
@@ -3900,7 +3899,7 @@ namespace OpenIddict.Server
}
};
- hash = CryptoConfig.CreateFromName(algorithm.Name) as HashAlgorithm;
+ hash = CryptoConfig.CreateFromName(algorithm.Name!) as HashAlgorithm;
}
return hash;
@@ -4034,7 +4033,7 @@ namespace OpenIddict.Server
Claims.Private.ExpirationDate or
Claims.Private.TokenType));
- if (principal is null)
+ if (principal is null or { Identity: not ClaimsIdentity })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0022));
}
@@ -4227,7 +4226,7 @@ namespace OpenIddict.Server
return default;
- static Uri? GetEndpointAbsoluteUri(Uri? issuer, Uri endpoint)
+ static Uri? GetEndpointAbsoluteUri(Uri? issuer, Uri? endpoint)
{
// If the endpoint is disabled (i.e a null address is specified), return null.
if (endpoint is null)
diff --git a/src/OpenIddict.Server/OpenIddictServerOptions.cs b/src/OpenIddict.Server/OpenIddictServerOptions.cs
index 5ecacdf6..60582ee5 100644
--- a/src/OpenIddict.Server/OpenIddictServerOptions.cs
+++ b/src/OpenIddict.Server/OpenIddictServerOptions.cs
@@ -80,7 +80,7 @@ namespace OpenIddict.Server
///
/// Gets the absolute and relative URIs associated to the cryptography endpoint.
///
- public List CryptographyEndpointUris { get; } = new List
+ public List CryptographyEndpointUris { get; } = new()
{
new Uri("/.well-known/jwks", UriKind.Relative)
};
diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs
index 927b29cc..1835ecd8 100644
--- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs
+++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
@@ -152,7 +153,7 @@ namespace OpenIddict.Validation.AspNetCore
else
{
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.Principal.GetTokenType()), SR.GetResourceString(SR.ID4009));
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID4010));
diff --git a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs
index 8d204700..a27d1c96 100644
--- a/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs
+++ b/src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs
@@ -186,7 +186,13 @@ namespace OpenIddict.Validation.DataProtection
foreach (var element in document.RootElement.EnumerateArray())
{
- builder.Add(element.GetString());
+ var item = element.GetString();
+ if (string.IsNullOrEmpty(item))
+ {
+ continue;
+ }
+
+ builder.Add(item);
}
return builder.ToImmutable();
diff --git a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
index 53940633..67c3885b 100644
--- a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
+++ b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
@@ -164,7 +164,7 @@ namespace OpenIddict.Validation.Owin
else
{
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.Principal.GetTokenType()), SR.GetResourceString(SR.ID4009));
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID4010));
diff --git a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
index 60c70a70..67d701b2 100644
--- a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
+++ b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
@@ -123,6 +123,7 @@ namespace OpenIddict.Validation.SystemNetHttp
throw new ArgumentNullException(nameof(context));
}
+ Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
@@ -133,22 +134,25 @@ namespace OpenIddict.Validation.SystemNetHttp
throw new InvalidOperationException(SR.GetResourceString(SR.ID0173));
}
- // Note: System.Net.Http doesn't expose convenient methods allowing to create
- // query strings from existing key/value pairs. To work around this limitation,
- // a FormUrlEncodedContent is instantiated and used to manually create the URL.
- using var content = new FormUrlEncodedContent(
- from parameter in context.Transaction.Request.GetParameters()
- let values = (string[]?) parameter.Value
- where values is not null
- from value in values
- select new KeyValuePair(parameter.Key, value));
-
- var builder = new UriBuilder(request.RequestUri)
+ if (request.RequestUri is not null)
{
- Query = await content.ReadAsStringAsync()
- };
-
- request.RequestUri = builder.Uri;
+ // Note: System.Net.Http doesn't expose convenient methods allowing to create
+ // query strings from existing key/value pairs. To work around this limitation,
+ // a FormUrlEncodedContent is instantiated and used to manually create the URL.
+ using var content = new FormUrlEncodedContent(
+ from parameter in context.Transaction.Request.GetParameters()
+ let values = (string[]?) parameter.Value
+ where values is not null
+ from value in values
+ select new KeyValuePair(parameter.Key, value));
+
+ var builder = new UriBuilder(request.RequestUri)
+ {
+ Query = await content.ReadAsStringAsync()
+ };
+
+ request.RequestUri = builder.Uri;
+ }
}
}
diff --git a/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs b/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
index 7106d22f..f8d77ef1 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
@@ -330,7 +330,7 @@ namespace Microsoft.Extensions.DependencyInjection
return AddEncryptionCertificate(certificate);
- static X509Certificate2 GetCertificate(StoreLocation location, string thumbprint)
+ static X509Certificate2? GetCertificate(StoreLocation location, string thumbprint)
{
using var store = new X509Store(StoreName.My, location);
store.Open(OpenFlags.ReadOnly);
diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs
index ca6dbd2d..04112d5d 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs
@@ -384,13 +384,19 @@ namespace OpenIddict.Validation
case JsonElement { ValueKind: JsonValueKind.Array } value:
foreach (var element in value.EnumerateArray())
{
- identity.AddClaim(new Claim(parameter.Key, element.ToString(),
+ var item = element.GetString();
+ if (string.IsNullOrEmpty(item))
+ {
+ continue;
+ }
+
+ identity.AddClaim(new Claim(parameter.Key, item,
GetClaimValueType(value.ValueKind), issuer, issuer, identity));
}
break;
case JsonElement value:
- identity.AddClaim(new Claim(parameter.Key, value.ToString(),
+ identity.AddClaim(new Claim(parameter.Key, value.ToString()!,
GetClaimValueType(value.ValueKind), issuer, issuer, identity));
break;
diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs
index c851c97e..8cbcc902 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs
@@ -641,7 +641,7 @@ namespace OpenIddict.Validation
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
var date = context.Principal.GetExpirationDate();
if (date.HasValue && date.Value < DateTimeOffset.UtcNow)
@@ -683,7 +683,7 @@ namespace OpenIddict.Validation
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
// If no explicit audience has been configured,
// skip the default audience validation.
@@ -755,7 +755,7 @@ namespace OpenIddict.Validation
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
var identifier = context.Principal.GetTokenId();
if (string.IsNullOrEmpty(identifier))
@@ -818,7 +818,7 @@ namespace OpenIddict.Validation
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
var identifier = context.Principal.GetAuthorizationId();
if (string.IsNullOrEmpty(identifier))
diff --git a/src/OpenIddict.Validation/OpenIddictValidationService.cs b/src/OpenIddict.Validation/OpenIddictValidationService.cs
index fb80bad3..d5dfbcbb 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationService.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationService.cs
@@ -458,7 +458,7 @@ namespace OpenIddict.Validation
context.Error, context.ErrorDescription, context.ErrorUri);
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
return context.Principal;
}
@@ -521,7 +521,7 @@ namespace OpenIddict.Validation
context.Error, context.ErrorDescription, context.ErrorUri);
}
- Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
+ Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
return context.Principal;
}
diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs
index b90389c1..62a911ee 100644
--- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs
+++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs
@@ -1169,9 +1169,9 @@ namespace OpenIddict.Abstractions.Tests.Primitives
principal.SetDestinations(destinations.ToImmutable());
// Assert
- Assert.Equal(@"[""access_token"",""id_token""]", principal.FindFirst(Claims.Name).Properties[Properties.Destinations]);
- Assert.Equal(@"[""id_token""]", principal.FindFirst(Claims.Email).Properties[Properties.Destinations]);
- Assert.DoesNotContain(Properties.Destinations, principal.FindFirst(Claims.Nonce).Properties);
+ Assert.Equal(@"[""access_token"",""id_token""]", principal.FindFirst(Claims.Name)!.Properties[Properties.Destinations]);
+ Assert.Equal(@"[""id_token""]", principal.FindFirst(Claims.Email)!.Properties[Properties.Destinations]);
+ Assert.DoesNotContain(Properties.Destinations, principal.FindFirst(Claims.Nonce)!.Properties);
}
[Theory]
@@ -1241,7 +1241,7 @@ namespace OpenIddict.Abstractions.Tests.Primitives
// Assert
Assert.Single(clone.Claims);
Assert.Null(clone.FindFirst(Claims.Subject));
- Assert.Equal("Bob le Bricoleur", clone.FindFirst(Claims.Name).Value);
+ Assert.Equal("Bob le Bricoleur", clone.FindFirst(Claims.Name)!.Value);
}
[Fact]
@@ -1259,9 +1259,9 @@ namespace OpenIddict.Abstractions.Tests.Primitives
var clone = identity.Clone(claim => claim.Type == Claims.Name);
// Assert
- Assert.Single(clone.Actor.Claims);
+ Assert.Single(clone.Actor!.Claims);
Assert.Null(clone.Actor.FindFirst(Claims.Subject));
- Assert.Equal("Bob le Bricoleur", clone.Actor.FindFirst(Claims.Name).Value);
+ Assert.Equal("Bob le Bricoleur", clone.Actor.FindFirst(Claims.Name)!.Value);
}
[Fact]
@@ -1280,7 +1280,7 @@ namespace OpenIddict.Abstractions.Tests.Primitives
// Assert
Assert.Single(clone.Claims);
Assert.Null(clone.FindFirst(Claims.Subject));
- Assert.Equal("Bob le Bricoleur", clone.FindFirst(Claims.Name).Value);
+ Assert.Equal("Bob le Bricoleur", clone.FindFirst(Claims.Name)!.Value);
}
[Fact]
@@ -1308,7 +1308,7 @@ namespace OpenIddict.Abstractions.Tests.Primitives
identity.AddClaim(Claims.Name, "Bob le Bricoleur");
// Assert
- Assert.Equal("Bob le Bricoleur", identity.FindFirst(Claims.Name).Value);
+ Assert.Equal("Bob le Bricoleur", identity.FindFirst(Claims.Name)!.Value);
}
[Theory]
@@ -1324,7 +1324,7 @@ namespace OpenIddict.Abstractions.Tests.Primitives
// Act
identity.AddClaim(Claims.Name, "Bob le Bricoleur", ImmutableArray.Create(destinations));
- var claim = identity.FindFirst(Claims.Name);
+ var claim = identity.FindFirst(Claims.Name)!;
// Assert
Assert.Equal("Bob le Bricoleur", claim.Value);
@@ -1344,7 +1344,7 @@ namespace OpenIddict.Abstractions.Tests.Primitives
// Act
identity.AddClaim(Claims.Name, "Bob le Bricoleur", destinations);
- var claim = identity.FindFirst(Claims.Name);
+ var claim = identity.FindFirst(Claims.Name)!;
// Assert
Assert.Equal("Bob le Bricoleur", claim.Value);
@@ -2422,13 +2422,27 @@ namespace OpenIddict.Abstractions.Tests.Primitives
Assert.Equal("principal", exception.ParamName);
}
+ [Fact]
+ public void SetClaim_ThrowsAnExceptionForNullIdentity()
+ {
+ // Arrange
+ var principal = new ClaimsPrincipal();
+
+ // Act and assert
+ var exception = Assert.Throws(() => principal.SetClaim("type", "value"));
+
+ Assert.Equal("principal", exception.ParamName);
+ Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message);
+ }
+
[Theory]
[InlineData(null)]
[InlineData("")]
- public void SetClaim_ThrowsAnExceptionForNullOrEmptyProperty(string type)
+ public void SetClaim_ThrowsAnExceptionForNullOrEmptyType(string type)
{
// Arrange
- var principal = new ClaimsPrincipal();
+ var identity = new ClaimsIdentity();
+ var principal = new ClaimsPrincipal(identity);
// Act and assert
var exception = Assert.Throws(() => principal.SetClaim(type, "value"));
diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs
index d192f982..de1f3cc9 100644
--- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs
+++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs
@@ -446,7 +446,7 @@ namespace OpenIddict.Abstractions.Tests.Primitives
""logo_uri"": ""https://client.example.org/logo.png"",
""jwks_uri"": ""https://client.example.org/my_public_keys.jwks"",
""example_extension_parameter"": ""example_value""
-}");
+}")!;
var options = new JsonSerializerOptions
{
diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs
index 2cef4d87..b91e8b90 100644
--- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs
+++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs
@@ -38,7 +38,7 @@ namespace OpenIddict.Abstractions.Tests.Primitives
}
[Fact]
- public void Count_ReturnsZeroForInteger()
+ public void Count_ReturnsZeroForLongValue()
{
// Arrange
var parameter = new OpenIddictParameter(42);
@@ -614,6 +614,24 @@ namespace OpenIddict.Abstractions.Tests.Primitives
Assert.Empty(parameter.ToString());
}
+ [Fact]
+ public void ToString_ReturnsBooleanValue()
+ {
+ // Arrange, act and assert
+ Assert.Equal(bool.TrueString, new OpenIddictParameter(true).ToString());
+ Assert.Equal(bool.FalseString, new OpenIddictParameter(false).ToString());
+ }
+
+ [Fact]
+ public void ToString_ReturnsLongValue()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter(42);
+
+ // Act and assert
+ Assert.Equal("42", parameter.ToString());
+ }
+
[Fact]
public void ToString_ReturnsStringValue()
{
diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs
index a294445f..78b93f55 100644
--- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs
+++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs
@@ -256,14 +256,14 @@ namespace OpenIddict.Server.IntegrationTests
// Note: a dictionary is deliberately not used here to allow multiple parameters with the
// same name to be specified. While initially not allowed by the core OAuth2 specification,
// this is required for derived drafts like the OAuth2 token exchange specification.
- var parameters = new List>();
+ var parameters = new List>();
foreach (var parameter in request.GetParameters())
{
// If the parameter is null or empty, send an empty value.
if (OpenIddictParameter.IsNullOrEmpty(parameter.Value))
{
- parameters.Add(new KeyValuePair(parameter.Key, string.Empty));
+ parameters.Add(new KeyValuePair(parameter.Key, string.Empty));
continue;
}
@@ -276,7 +276,7 @@ namespace OpenIddict.Server.IntegrationTests
foreach (var value in values)
{
- parameters.Add(new KeyValuePair(parameter.Key, value));
+ parameters.Add(new KeyValuePair(parameter.Key, value));
}
}
@@ -286,19 +286,28 @@ namespace OpenIddict.Server.IntegrationTests
foreach (var parameter in parameters)
{
+ if (string.IsNullOrEmpty(parameter.Key))
+ {
+ continue;
+ }
+
if (builder.Length != 0)
{
builder.Append('&');
}
builder.Append(UrlEncoder.Default.Encode(parameter.Key));
- builder.Append('=');
- builder.Append(UrlEncoder.Default.Encode(parameter.Value));
+
+ if (!string.IsNullOrEmpty(parameter.Value))
+ {
+ builder.Append('=');
+ builder.Append(UrlEncoder.Default.Encode(parameter.Value));
+ }
}
if (!uri.IsAbsoluteUri)
{
- uri = new Uri(HttpClient.BaseAddress, uri);
+ uri = new Uri(HttpClient.BaseAddress!, uri);
}
uri = new UriBuilder(uri) { Query = builder.ToString() }.Uri;
diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs
index 6fb41f55..2b8b38a0 100644
--- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs
+++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs
@@ -238,8 +238,7 @@ namespace OpenIddict.Server.IntegrationTests
var response = await client.GetAsync("/.well-known/openid-configuration");
// Assert
- Assert.Equal(client.HttpClient.BaseAddress.AbsoluteUri,
- (string?) response[Metadata.Issuer]);
+ Assert.Equal(client.HttpClient.BaseAddress!.AbsoluteUri, (string?) response[Metadata.Issuer]);
}
[Fact]
@@ -257,8 +256,7 @@ namespace OpenIddict.Server.IntegrationTests
var response = await client.GetAsync("/.well-known/openid-configuration");
// Assert
- Assert.Equal("https://www.fabrikam.com/",
- (string?) response[Metadata.Issuer]);
+ Assert.Equal("https://www.fabrikam.com/", (string?) response[Metadata.Issuer]);
}
[Fact]