Versatile OpenID Connect stack for ASP.NET Core and Microsoft.Owin (compatible with ASP.NET 4.6.1)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

155 lines
7.2 KiB

/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using static OpenIddict.Abstractions.OpenIddictConstants;
namespace OpenIddict.Validation
{
/// <summary>
/// Provides various settings needed to configure the OpenIddict validation handler.
/// </summary>
public class OpenIddictValidationOptions
{
/// <summary>
/// Gets the list of credentials used to encrypt the tokens issued by the
/// OpenIddict validation services. Note: only symmetric credentials are supported.
/// </summary>
public List<EncryptingCredentials> EncryptionCredentials { get; } = new List<EncryptingCredentials>();
/// <summary>
/// Gets or sets the JWT handler used to protect and unprotect tokens.
/// </summary>
public JsonWebTokenHandler JsonWebTokenHandler { get; set; } = new JsonWebTokenHandler
{
SetDefaultTimesOnTokenCreation = false
};
/// <summary>
/// Gets the list of the handlers responsible of processing the OpenIddict validation operations.
/// Note: the list is automatically sorted based on the order assigned to each handler descriptor.
/// As such, it MUST NOT be mutated after options initialization to preserve the exact order.
/// </summary>
public List<OpenIddictValidationHandlerDescriptor> Handlers { get; } =
new List<OpenIddictValidationHandlerDescriptor>(OpenIddictValidationHandlers.DefaultHandlers);
/// <summary>
/// Gets or sets the type of validation used by the OpenIddict validation services.
/// By default, local validation is always used.
/// </summary>
public OpenIddictValidationType ValidationType { get; set; } = OpenIddictValidationType.Direct;
/// <summary>
/// Gets or sets the client identifier sent to the authorization server when using remote validation.
/// </summary>
public string ClientId { get; set; }
/// <summary>
/// Gets or sets the client secret sent to the authorization server when using remote validation.
/// </summary>
public string ClientSecret { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether a database call is made
/// to validate the authorization entry associated with the received tokens.
/// Note: enabling this option may have an impact on performance and
/// can only be used with an OpenIddict-based authorization server.
/// </summary>
public bool EnableAuthorizationEntryValidation { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether a database call is made
/// to validate the token entry associated with the received tokens.
/// Note: enabling this option may have an impact on performance but
/// is required when the OpenIddict server emits reference tokens.
/// </summary>
public bool EnableTokenEntryValidation { get; set; }
/// <summary>
/// Gets or sets the absolute URL of the OAuth 2.0/OpenID Connect server.
/// </summary>
public Uri Issuer { get; set; }
/// <summary>
/// Gets or sets the URL of the OAuth 2.0/OpenID Connect server discovery endpoint.
/// When the URL is relative, <see cref="Issuer"/> must be set and absolute.
/// </summary>
public Uri MetadataAddress { get; set; }
/// <summary>
/// Gets or sets the OAuth 2.0/OpenID Connect static server configuration, if applicable.
/// </summary>
public OpenIdConnectConfiguration Configuration { get; set; }
/// <summary>
/// Gets or sets the configuration manager used to retrieve
/// and cache the OAuth 2.0/OpenID Connect server configuration.
/// </summary>
public IConfigurationManager<OpenIdConnectConfiguration> ConfigurationManager { get; set; }
/// <summary>
/// Gets the intended audiences of this resource server.
/// Setting this property is recommended when the authorization
/// server issues access tokens for multiple distinct resource servers.
/// </summary>
public HashSet<string> Audiences { get; } = new HashSet<string>(StringComparer.Ordinal);
/// <summary>
/// Gets the token validation parameters used by the OpenIddict validation services.
/// </summary>
public TokenValidationParameters TokenValidationParameters { get; } = new TokenValidationParameters
{
AuthenticationType = TokenValidationParameters.DefaultAuthenticationType,
ClockSkew = TimeSpan.Zero,
NameClaimType = Claims.Name,
RoleClaimType = Claims.Role,
// In previous versions of OpenIddict (1.x and 2.x), all the JWT tokens (access and identity tokens)
// were issued with the generic "typ": "JWT" header. To prevent confused deputy and token substitution
// attacks, a special "token_usage" claim was added to the JWT payload to convey the actual token type.
// This validator overrides the default logic used by IdentityModel to resolve the type from this claim.
TypeValidator = (type, token, parameters) =>
{
if (string.IsNullOrEmpty(type))
{
throw new SecurityTokenInvalidTypeException("The 'typ' header of the JWT token cannot be null or empty.");
}
// If available, try to resolve the actual type from the "token_usage" claim.
if (((JsonWebToken) token).TryGetPayloadValue(Claims.TokenUsage, out string usage))
{
type = usage switch
{
TokenTypeHints.AccessToken => JsonWebTokenTypes.AccessToken,
TokenTypeHints.IdToken => JsonWebTokenTypes.IdentityToken,
_ => throw new NotSupportedException("The token usage of the JWT token is not supported.")
};
}
// Unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons.
if (parameters.ValidTypes != null && parameters.ValidTypes.Any() &&
!parameters.ValidTypes.Contains(type, StringComparer.OrdinalIgnoreCase))
{
throw new SecurityTokenInvalidTypeException("The type of the JWT token doesn't match the expected type.")
{
InvalidType = type
};
}
return type;
},
// Note: audience and lifetime are manually validated by OpenIddict itself.
ValidateAudience = false,
ValidateLifetime = false
};
}
}