/* * 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.ComponentModel; using System.Security.Claims; using Microsoft.Extensions.Logging; namespace OpenIddict.Server; public static partial class OpenIddictServerEvents { /// /// Represents an abstract base class used for certain event contexts. /// [EditorBrowsable(EditorBrowsableState.Never)] public abstract class BaseContext { /// /// Creates a new instance of the class. /// protected BaseContext(OpenIddictServerTransaction transaction) => Transaction = transaction ?? throw new ArgumentNullException(nameof(transaction)); /// /// Gets the environment associated with the current request being processed. /// public OpenIddictServerTransaction Transaction { get; } /// /// Gets or sets the cancellation token that will be /// used to determine if the operation was aborted. /// /// /// Note: for security reasons, this property shouldn't be used by event /// handlers to abort security-sensitive operations. As such, it is /// recommended to use this property only for user-dependent operations. /// public CancellationToken CancellationToken { get => Transaction.CancellationToken; set => Transaction.CancellationToken = value; } /// /// Gets or sets the endpoint type that handled the request, if applicable. /// public OpenIddictServerEndpointType EndpointType { get => Transaction.EndpointType; set => Transaction.EndpointType = value; } /// /// Gets or sets the request of the current transaction, if available. /// public Uri? RequestUri { get => Transaction.RequestUri; set => Transaction.RequestUri = value; } /// /// Gets or sets the base of the host, if available. /// public Uri? BaseUri { get => Transaction.BaseUri; set => Transaction.BaseUri = value; } /// /// Gets the logger responsible for logging processed operations. /// public ILogger Logger => Transaction.Logger; /// /// Gets the OpenIddict server options. /// public OpenIddictServerOptions Options => Transaction.Options; } /// /// Represents an abstract base class used for certain event contexts. /// [EditorBrowsable(EditorBrowsableState.Never)] public abstract class BaseRequestContext : BaseContext { /// /// Creates a new instance of the class. /// protected BaseRequestContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets a boolean indicating whether the request was fully handled. /// public bool IsRequestHandled { get; private set; } /// /// Gets a boolean indicating whether the request processing was skipped. /// public bool IsRequestSkipped { get; private set; } /// /// Marks the request as fully handled. Once declared handled, /// a request shouldn't be processed further by the underlying host. /// public void HandleRequest() => IsRequestHandled = true; /// /// Marks the request as skipped. Once declared skipped, a request /// shouldn't be processed further by OpenIddict but should be allowed /// to go through the next components in the processing pipeline /// (if this pattern is supported by the underlying host). /// public void SkipRequest() => IsRequestSkipped = true; } /// /// Represents an abstract base class used for certain event contexts. /// [EditorBrowsable(EditorBrowsableState.Never)] public abstract class BaseValidatingClientContext : BaseValidatingContext { /// /// Creates a new instance of the class. /// protected BaseValidatingClientContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets the "client_id" parameter for the current request. /// The authorization server application is responsible for /// validating this value to ensure it identifies a registered client. /// public string? ClientId => Transaction.Request?.ClientId; /// /// Gets the "client_secret" parameter for the current request. /// The authorization server application is responsible for /// validating this value to ensure it identifies a registered client. /// public string? ClientSecret => Transaction.Request?.ClientSecret; } /// /// Represents an abstract base class used for certain event contexts. /// [EditorBrowsable(EditorBrowsableState.Never)] public abstract class BaseValidatingContext : BaseRequestContext { /// /// Creates a new instance of the class. /// protected BaseValidatingContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets a boolean indicating whether the request will be rejected. /// public bool IsRejected { get; protected set; } /// /// Gets or sets the "error" parameter returned to the client application. /// public string? Error { get; private set; } /// /// Gets or sets the "error_description" parameter returned to the client application. /// public string? ErrorDescription { get; private set; } /// /// Gets or sets the "error_uri" parameter returned to the client application. /// public string? ErrorUri { get; private set; } /// /// Rejects the request. /// /// The "error" parameter returned to the client application. /// The "error_description" parameter returned to the client application. /// The "error_uri" parameter returned to the client application. public virtual void Reject(string? error = null, string? description = null, string? uri = null) { Error = error; ErrorDescription = description; ErrorUri = uri; IsRejected = true; } } /// /// Represents an abstract base class used for certain event contexts. /// [EditorBrowsable(EditorBrowsableState.Never)] public abstract class BaseValidatingTicketContext : BaseValidatingContext { /// /// Creates a new instance of the class. /// protected BaseValidatingTicketContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets or sets the security principal. /// public ClaimsPrincipal? Principal { get; set; } /// /// Gets the client identifier, or if the client application is unknown. /// public string? ClientId => Transaction.Request?.ClientId; } /// /// Represents an event called when processing an incoming request. /// public sealed class ProcessRequestContext : BaseValidatingContext { /// /// Creates a new instance of the class. /// public ProcessRequestContext(OpenIddictServerTransaction transaction) : base(transaction) { } } /// /// Represents an event called when processing an errored response. /// public sealed class ProcessErrorContext : BaseRequestContext { /// /// Creates a new instance of the class. /// public ProcessErrorContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets or sets the request or if it couldn't be extracted. /// public OpenIddictRequest? Request { get => Transaction.Request; set => Transaction.Request = value; } /// /// Gets or sets the response. /// public OpenIddictResponse Response { get => Transaction.Response!; set => Transaction.Response = value; } /// /// Gets or sets the error returned to the caller. /// public string? Error { get; set; } /// /// Gets or sets the error description returned to the caller. /// public string? ErrorDescription { get; set; } /// /// Gets or sets the error URI returned to the caller. /// public string? ErrorUri { get; set; } /// /// Gets the additional parameters returned to the caller. /// public Dictionary Parameters { get; } = new(StringComparer.Ordinal); } /// /// Represents an event called when processing an authentication operation. /// public sealed class ProcessAuthenticationContext : BaseValidatingClientContext { /// /// Creates a new instance of the class. /// public ProcessAuthenticationContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets or sets the request. /// public OpenIddictRequest Request { get => Transaction.Request!; set => Transaction.Request = value; } /// /// Gets the user-defined authentication properties, if available. /// public Dictionary Properties { get; } = new(StringComparer.Ordinal); /// /// Gets or sets a boolean indicating whether an access /// token should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractAccessToken { get; set; } /// /// Gets or sets a boolean indicating whether an authorization /// code should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractAuthorizationCode { get; set; } /// /// Gets or sets a boolean indicating whether a client assertion /// token should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractClientAssertion { get; set; } /// /// Gets or sets a boolean indicating whether a device /// code should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractDeviceCode { get; set; } /// /// Gets or sets a boolean indicating whether a generic /// token should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractGenericToken { get; set; } /// /// Gets or sets a boolean indicating whether an identity /// token should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractIdentityToken { get; set; } /// /// Gets or sets a boolean indicating whether a refresh /// token should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractRefreshToken { get; set; } /// /// Gets or sets a boolean indicating whether a user /// code should be extracted from the current context. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ExtractUserCode { get; set; } /// /// Gets or sets a boolean indicating whether an access token /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireAccessToken { get; set; } /// /// Gets or sets a boolean indicating whether an authorization code /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireAuthorizationCode { get; set; } /// /// Gets or sets a boolean indicating whether a client assertion /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireClientAssertion { get; set; } /// /// Gets or sets a boolean indicating whether a device code /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireDeviceCode { get; set; } /// /// Gets or sets a boolean indicating whether a generic token /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireGenericToken { get; set; } /// /// Gets or sets a boolean indicating whether an identity token /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireIdentityToken { get; set; } /// /// Gets or sets a boolean indicating whether a refresh token /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireRefreshToken { get; set; } /// /// Gets or sets a boolean indicating whether a user code /// must be resolved for the authentication to be considered valid. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RequireUserCode { get; set; } /// /// Gets or sets a boolean indicating whether the access /// token extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateAccessToken { get; set; } /// /// Gets or sets a boolean indicating whether the authorization /// code extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateAuthorizationCode { get; set; } /// /// Gets or sets a boolean indicating whether the client assertion /// token extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateClientAssertion { get; set; } /// /// Gets or sets a boolean indicating whether the device /// code extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateDeviceCode { get; set; } /// /// Gets or sets a boolean indicating whether the generic /// token extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateGenericToken { get; set; } /// /// Gets or sets a boolean indicating whether the identity /// token extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateIdentityToken { get; set; } /// /// Gets or sets a boolean indicating whether the refresh /// token extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateRefreshToken { get; set; } /// /// Gets or sets a boolean indicating whether the user /// code extracted from the current request should be validated. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool ValidateUserCode { get; set; } /// /// Gets or sets a boolean indicating whether an invalid access token /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectAccessToken { get; set; } /// /// Gets or sets a boolean indicating whether an invalid authorization code /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectAuthorizationCode { get; set; } /// /// Gets or sets a boolean indicating whether an invalid client assertion /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectClientAssertion { get; set; } /// /// Gets or sets a boolean indicating whether an invalid device code /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectDeviceCode { get; set; } /// /// Gets or sets a boolean indicating whether an invalid generic token /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectGenericToken { get; set; } /// /// Gets or sets a boolean indicating whether an invalid identity token /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectIdentityToken { get; set; } /// /// Gets or sets a boolean indicating whether an invalid refresh token /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectRefreshToken { get; set; } /// /// Gets or sets a boolean indicating whether an invalid user code /// will cause the authentication demand to be rejected or will be ignored. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool RejectUserCode { get; set; } /// /// Gets or sets the access token to validate, if applicable. /// public string? AccessToken { get; set; } /// /// Gets or sets the principal extracted from the access token, if applicable. /// public ClaimsPrincipal? AccessTokenPrincipal { get; set; } /// /// Gets or sets the authorization code to validate, if applicable. /// public string? AuthorizationCode { get; set; } /// /// Gets or sets the principal extracted from the authorization code, if applicable. /// public ClaimsPrincipal? AuthorizationCodePrincipal { get; set; } /// /// Gets or sets the client assertion to validate, if applicable. /// public string? ClientAssertion { get; set; } /// /// Gets or sets the type of the client assertion to validate, if applicable. /// public string? ClientAssertionType { get; set; } /// /// Gets or sets the principal extracted from the client assertion, if applicable. /// public ClaimsPrincipal? ClientAssertionPrincipal { get; set; } /// /// Gets or sets the device code to validate, if applicable. /// public string? DeviceCode { get; set; } /// /// Gets or sets the principal extracted from the device code, if applicable. /// public ClaimsPrincipal? DeviceCodePrincipal { get; set; } /// /// Gets or sets the generic token to validate, if applicable. /// public string? GenericToken { get; set; } /// /// Gets or sets the optional hint indicating the type of the generic token, if applicable. /// public string? GenericTokenTypeHint { get; set; } /// /// Gets or sets the principal extracted from the generic token, if applicable. /// public ClaimsPrincipal? GenericTokenPrincipal { get; set; } /// /// Gets or sets the identity token to validate, if applicable. /// public string? IdentityToken { get; set; } /// /// Gets or sets the principal extracted from the identity token, if applicable. /// public ClaimsPrincipal? IdentityTokenPrincipal { get; set; } /// /// Gets or sets the refresh token to validate, if applicable. /// public string? RefreshToken { get; set; } /// /// Gets or sets the principal extracted from the refresh token, if applicable. /// public ClaimsPrincipal? RefreshTokenPrincipal { get; set; } /// /// Gets or sets the user code to validate, if applicable. /// public string? UserCode { get; set; } /// /// Gets or sets the principal extracted from the user code, if applicable. /// public ClaimsPrincipal? UserCodePrincipal { get; set; } } /// /// Represents an event called when processing a challenge operation. /// public sealed class ProcessChallengeContext : BaseValidatingContext { /// /// Creates a new instance of the class. /// public ProcessChallengeContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets or sets the request. /// public OpenIddictRequest Request { get => Transaction.Request!; set => Transaction.Request = value; } /// /// Gets or sets the response. /// public OpenIddictResponse Response { get => Transaction.Response!; set => Transaction.Response = value; } /// /// Gets the user-defined authentication properties, if available. /// public Dictionary Properties { get; } = new(StringComparer.Ordinal); /// /// Gets the additional parameters returned to the caller. /// public Dictionary Parameters { get; } = new(StringComparer.Ordinal); } /// /// Represents an event called when processing a sign-in response. /// public sealed class ProcessSignInContext : BaseValidatingTicketContext { /// /// Creates a new instance of the class. /// public ProcessSignInContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets or sets the request. /// public OpenIddictRequest Request { get => Transaction.Request!; set => Transaction.Request = value; } /// /// Gets or sets the response. /// public OpenIddictResponse Response { get => Transaction.Response!; set => Transaction.Response = value; } /// /// Gets the user-defined authentication properties, if available. /// public Dictionary Properties { get; } = new(StringComparer.Ordinal); /// /// Gets the additional parameters returned to the caller. /// public Dictionary Parameters { get; } = new(StringComparer.Ordinal); /// /// Gets or sets a boolean indicating whether an access token /// should be generated (and optionally returned to the client). /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool GenerateAccessToken { get; set; } /// /// Gets or sets a boolean indicating whether an authorization code /// should be generated (and optionally returned to the client). /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool GenerateAuthorizationCode { get; set; } /// /// Gets or sets a boolean indicating whether a device code /// should be generated (and optionally returned to the client). /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool GenerateDeviceCode { get; set; } /// /// Gets or sets a boolean indicating whether an identity token /// should be generated (and optionally returned to the client). /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool GenerateIdentityToken { get; set; } /// /// Gets or sets a boolean indicating whether a refresh token /// should be generated (and optionally returned to the client). /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool GenerateRefreshToken { get; set; } /// /// Gets or sets a boolean indicating whether a user code /// should be generated (and optionally returned to the client). /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool GenerateUserCode { get; set; } /// /// Gets or sets a boolean indicating whether the generated access token /// should be returned to the client application as part of the response. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool IncludeAccessToken { get; set; } /// /// Gets or sets a boolean indicating whether the generated authorization code /// should be returned to the client application as part of the response. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool IncludeAuthorizationCode { get; set; } /// /// Gets or sets a boolean indicating whether the generated device code /// should be returned to the client application as part of the response. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool IncludeDeviceCode { get; set; } /// /// Gets or sets a boolean indicating whether the generated identity token /// should be returned to the client application as part of the response. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool IncludeIdentityToken { get; set; } /// /// Gets or sets a boolean indicating whether the generated refresh token /// should be returned to the client application as part of the response. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool IncludeRefreshToken { get; set; } /// /// Gets or sets a boolean indicating whether the generated user code /// should be returned to the client application as part of the response. /// /// /// Note: overriding the value of this property is generally not recommended. /// public bool IncludeUserCode { get; set; } /// /// Gets or sets the generated access token, if applicable. /// The access token will only be returned if /// is set to . /// public string? AccessToken { get; set; } /// /// Gets or sets the principal containing the claims that /// will be used to create the access token, if applicable. /// public ClaimsPrincipal? AccessTokenPrincipal { get; set; } /// /// Gets or sets the generated authorization code, if applicable. /// The authorization code will only be returned if /// is set to . /// public string? AuthorizationCode { get; set; } /// /// Gets or sets the principal containing the claims that /// will be used to create the authorization code, if applicable. /// public ClaimsPrincipal? AuthorizationCodePrincipal { get; set; } /// /// Gets or sets the generated device code, if applicable. /// The device code will only be returned if /// is set to . /// public string? DeviceCode { get; set; } /// /// Gets or sets the principal containing the claims that /// will be used to create the device code, if applicable. /// public ClaimsPrincipal? DeviceCodePrincipal { get; set; } /// /// Gets or sets the generated identity token, if applicable. /// The identity token will only be returned if /// is set to . /// public string? IdentityToken { get; set; } /// /// Gets or sets the principal containing the claims that /// will be used to create the identity token, if applicable. /// public ClaimsPrincipal? IdentityTokenPrincipal { get; set; } /// /// Gets or sets the generated refresh token, if applicable. /// The refresh token will only be returned if /// is set to . /// public string? RefreshToken { get; set; } /// /// Gets or sets the principal containing the claims that /// will be used to create the refresh token, if applicable. /// public ClaimsPrincipal? RefreshTokenPrincipal { get; set; } /// /// Gets or sets the generated user code, if applicable. /// The user code will only be returned if /// is set to . /// public string? UserCode { get; set; } /// /// Gets or sets the principal containing the claims that /// will be used to create the user code, if applicable. /// public ClaimsPrincipal? UserCodePrincipal { get; set; } } /// /// Represents an event called when processing a sign-out response. /// public sealed class ProcessSignOutContext : BaseValidatingContext { /// /// Creates a new instance of the class. /// public ProcessSignOutContext(OpenIddictServerTransaction transaction) : base(transaction) { } /// /// Gets or sets the request. /// public OpenIddictRequest Request { get => Transaction.Request!; set => Transaction.Request = value; } /// /// Gets or sets the response. /// public OpenIddictResponse Response { get => Transaction.Response!; set => Transaction.Response = value; } /// /// Gets the user-defined authentication properties, if available. /// public Dictionary Properties { get; } = new(StringComparer.Ordinal); /// /// Gets the additional parameters returned to the caller. /// public Dictionary Parameters { get; } = new(StringComparer.Ordinal); } }