42 changed files with 1517 additions and 604 deletions
@ -0,0 +1,7 @@ |
|||||
|
namespace OpenIddict.Server |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents an OpenIddict server event.
|
||||
|
/// </summary>
|
||||
|
public interface IOpenIddictServerEvent { } |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Server |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a handler able to process <typeparamref name="TEvent"/> events.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the events handled by this instance.</typeparam>
|
||||
|
public interface IOpenIddictServerEventHandler<TEvent> where TEvent : class, IOpenIddictServerEvent |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Processes the event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="notification">The event to process.</param>
|
||||
|
/// <param name="cancellationToken">
|
||||
|
/// The <see cref="CancellationToken"/> that can be used to abort the operation.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
|
||||
|
/// </returns>
|
||||
|
Task HandleAsync([NotNull] TEvent notification, CancellationToken cancellationToken); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Server |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Dispatches events by invoking the corresponding handlers.
|
||||
|
/// </summary>
|
||||
|
public interface IOpenIddictServerEventService |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Publishes a new event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the event to publish.</typeparam>
|
||||
|
/// <param name="notification">The event to publish.</param>
|
||||
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
|
||||
|
/// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns>
|
||||
|
Task PublishAsync<TEvent>([NotNull] TEvent notification, CancellationToken cancellationToken = default) |
||||
|
where TEvent : class, IOpenIddictServerEvent; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Server |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents an OpenIddict server event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TContext">The type of the context instance associated with the event.</typeparam>
|
||||
|
public class OpenIddictServerEvent<TContext> : IOpenIddictServerEvent where TContext : class |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="OpenIddictServerEvent{TContext}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the event.</param>
|
||||
|
public OpenIddictServerEvent([NotNull] TContext context) |
||||
|
=> Context = context ?? throw new ArgumentNullException(nameof(context)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the context instance associated with the event.
|
||||
|
/// </summary>
|
||||
|
public TContext Context { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Server |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a handler able to process <typeparamref name="TEvent"/> events.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the events handled by this instance.</typeparam>
|
||||
|
public class OpenIddictServerEventHandler<TEvent> : IOpenIddictServerEventHandler<TEvent> |
||||
|
where TEvent : class, IOpenIddictServerEvent |
||||
|
{ |
||||
|
private readonly Func<TEvent, CancellationToken, Task> _handler; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new event using the specified handler delegate.
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler">The event handler delegate</param>
|
||||
|
public OpenIddictServerEventHandler([NotNull] Func<TEvent, CancellationToken, Task> handler) |
||||
|
=> _handler = handler ?? throw new ArgumentNullException(nameof(handler)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Processes the event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="notification">The event to process.</param>
|
||||
|
/// <param name="cancellationToken">
|
||||
|
/// The <see cref="CancellationToken"/> that can be used to abort the operation.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
|
||||
|
/// </returns>
|
||||
|
public Task HandleAsync(TEvent notification, CancellationToken cancellationToken) |
||||
|
{ |
||||
|
if (notification == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(notification)); |
||||
|
} |
||||
|
|
||||
|
if (cancellationToken.IsCancellationRequested) |
||||
|
{ |
||||
|
return Task.FromCanceled(cancellationToken); |
||||
|
} |
||||
|
|
||||
|
return _handler.Invoke(notification, cancellationToken); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,150 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using AspNet.Security.OpenIdConnect.Primitives; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using static OpenIddict.Server.OpenIddictServerEvents; |
||||
|
|
||||
|
namespace OpenIddict.Server |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Dispatches notifications by invoking the corresponding handlers.
|
||||
|
/// </summary>
|
||||
|
public class OpenIddictServerEventService : IOpenIddictServerEventService |
||||
|
{ |
||||
|
private readonly IServiceProvider _provider; |
||||
|
|
||||
|
public OpenIddictServerEventService([NotNull] IServiceProvider provider) |
||||
|
{ |
||||
|
_provider = provider; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Publishes a new event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the event to publish.</typeparam>
|
||||
|
/// <param name="notification">The event to publish.</param>
|
||||
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
|
||||
|
/// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns>
|
||||
|
public async Task PublishAsync<TEvent>([NotNull] TEvent notification, CancellationToken cancellationToken = default) |
||||
|
where TEvent : class, IOpenIddictServerEvent |
||||
|
{ |
||||
|
if (notification == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(notification)); |
||||
|
} |
||||
|
|
||||
|
foreach (var handler in _provider.GetServices<IOpenIddictServerEventHandler<TEvent>>()) |
||||
|
{ |
||||
|
cancellationToken.ThrowIfCancellationRequested(); |
||||
|
|
||||
|
await handler.HandleAsync(notification, cancellationToken); |
||||
|
|
||||
|
// Note: the following logic determines whether next handlers should be invoked
|
||||
|
// depending on whether the underlying event context was substantially updated.
|
||||
|
switch (notification) |
||||
|
{ |
||||
|
case MatchEndpoint value when value.Context.Result != null: return; |
||||
|
case MatchEndpoint value when value.Context.IsAuthorizationEndpoint || |
||||
|
value.Context.IsConfigurationEndpoint || |
||||
|
value.Context.IsCryptographyEndpoint || |
||||
|
value.Context.IsIntrospectionEndpoint || |
||||
|
value.Context.IsLogoutEndpoint || |
||||
|
value.Context.IsRevocationEndpoint || |
||||
|
value.Context.IsTokenEndpoint || |
||||
|
value.Context.IsUserinfoEndpoint: return; |
||||
|
|
||||
|
case ExtractAuthorizationRequest value when value.Context.Result != null: return; |
||||
|
case ExtractConfigurationRequest value when value.Context.Result != null: return; |
||||
|
case ExtractCryptographyRequest value when value.Context.Result != null: return; |
||||
|
case ExtractIntrospectionRequest value when value.Context.Result != null: return; |
||||
|
case ExtractLogoutRequest value when value.Context.Result != null: return; |
||||
|
case ExtractRevocationRequest value when value.Context.Result != null: return; |
||||
|
case ExtractTokenRequest value when value.Context.Result != null: return; |
||||
|
case ExtractUserinfoRequest value when value.Context.Result != null: return; |
||||
|
|
||||
|
case ValidateAuthorizationRequest value when value.Context.Result != null: return; |
||||
|
case ValidateConfigurationRequest value when value.Context.Result != null: return; |
||||
|
case ValidateCryptographyRequest value when value.Context.Result != null: return; |
||||
|
case ValidateIntrospectionRequest value when value.Context.Result != null: return; |
||||
|
case ValidateLogoutRequest value when value.Context.Result != null: return; |
||||
|
case ValidateRevocationRequest value when value.Context.Result != null: return; |
||||
|
case ValidateTokenRequest value when value.Context.Result != null: return; |
||||
|
case ValidateUserinfoRequest value when value.Context.Result != null: return; |
||||
|
|
||||
|
case ValidateAuthorizationRequest value when value.Context.IsRejected: return; |
||||
|
case ValidateConfigurationRequest value when value.Context.IsRejected: return; |
||||
|
case ValidateCryptographyRequest value when value.Context.IsRejected: return; |
||||
|
case ValidateIntrospectionRequest value when value.Context.IsRejected: return; |
||||
|
case ValidateLogoutRequest value when value.Context.IsRejected: return; |
||||
|
case ValidateRevocationRequest value when value.Context.IsRejected: return; |
||||
|
case ValidateTokenRequest value when value.Context.IsRejected: return; |
||||
|
case ValidateUserinfoRequest value when value.Context.IsRejected: return; |
||||
|
|
||||
|
case ValidateIntrospectionRequest value when value.Context.IsSkipped: return; |
||||
|
case ValidateRevocationRequest value when value.Context.IsSkipped: return; |
||||
|
case ValidateTokenRequest value when value.Context.IsSkipped: return; |
||||
|
|
||||
|
case HandleAuthorizationRequest value when value.Context.Result != null: return; |
||||
|
case HandleConfigurationRequest value when value.Context.Result != null: return; |
||||
|
case HandleCryptographyRequest value when value.Context.Result != null: return; |
||||
|
case HandleIntrospectionRequest value when value.Context.Result != null: return; |
||||
|
case HandleLogoutRequest value when value.Context.Result != null: return; |
||||
|
case HandleRevocationRequest value when value.Context.Result != null: return; |
||||
|
case HandleTokenRequest value when value.Context.Result != null: return; |
||||
|
case HandleUserinfoRequest value when value.Context.Result != null: return; |
||||
|
|
||||
|
case HandleAuthorizationRequest value when value.Context.Ticket != null: return; |
||||
|
|
||||
|
case HandleTokenRequest value when value.Context.Ticket != null && |
||||
|
!value.Context.Request.IsAuthorizationCodeGrantType() && |
||||
|
!value.Context.Request.IsRefreshTokenGrantType(): return; |
||||
|
|
||||
|
case HandleTokenRequest value when value.Context.Ticket == null && |
||||
|
(value.Context.Request.IsAuthorizationCodeGrantType() || |
||||
|
value.Context.Request.IsRefreshTokenGrantType()): return; |
||||
|
|
||||
|
case HandleAuthorizationRequest value when value.Context.Ticket != null: return; |
||||
|
|
||||
|
case ProcessChallengeResponse value when value.Context.Result != null: return; |
||||
|
case ProcessSigninResponse value when value.Context.Result != null: return; |
||||
|
case ProcessSignoutResponse value when value.Context.Result != null: return; |
||||
|
|
||||
|
case ProcessChallengeResponse value when value.Context.IsRejected: return; |
||||
|
case ProcessSigninResponse value when value.Context.IsRejected: return; |
||||
|
case ProcessSignoutResponse value when value.Context.IsRejected: return; |
||||
|
|
||||
|
case ApplyAuthorizationResponse value when value.Context.Result != null: return; |
||||
|
case ApplyConfigurationResponse value when value.Context.Result != null: return; |
||||
|
case ApplyCryptographyResponse value when value.Context.Result != null: return; |
||||
|
case ApplyIntrospectionResponse value when value.Context.Result != null: return; |
||||
|
case ApplyLogoutResponse value when value.Context.Result != null: return; |
||||
|
case ApplyRevocationResponse value when value.Context.Result != null: return; |
||||
|
case ApplyTokenResponse value when value.Context.Result != null: return; |
||||
|
case ApplyUserinfoResponse value when value.Context.Result != null: return; |
||||
|
|
||||
|
case DeserializeAuthorizationCode value when value.Context.IsHandled: return; |
||||
|
case DeserializeAccessToken value when value.Context.IsHandled: return; |
||||
|
case DeserializeIdentityToken value when value.Context.IsHandled: return; |
||||
|
case DeserializeRefreshToken value when value.Context.IsHandled: return; |
||||
|
|
||||
|
case DeserializeAuthorizationCode value when value.Context.Ticket != null: return; |
||||
|
case DeserializeAccessToken value when value.Context.Ticket != null: return; |
||||
|
case DeserializeIdentityToken value when value.Context.Ticket != null: return; |
||||
|
case DeserializeRefreshToken value when value.Context.Ticket != null: return; |
||||
|
|
||||
|
case SerializeAuthorizationCode value when value.Context.IsHandled: return; |
||||
|
case SerializeAccessToken value when value.Context.IsHandled: return; |
||||
|
case SerializeIdentityToken value when value.Context.IsHandled: return; |
||||
|
case SerializeRefreshToken value when value.Context.IsHandled: return; |
||||
|
|
||||
|
case SerializeAuthorizationCode value when !string.IsNullOrEmpty(value.Context.AuthorizationCode): return; |
||||
|
case SerializeAccessToken value when !string.IsNullOrEmpty(value.Context.AccessToken): return; |
||||
|
case SerializeIdentityToken value when !string.IsNullOrEmpty(value.Context.IdentityToken): return; |
||||
|
case SerializeRefreshToken value when !string.IsNullOrEmpty(value.Context.RefreshToken): return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,565 @@ |
|||||
|
using AspNet.Security.OpenIdConnect.Server; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Server |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Contains common events used by the OpenIddict server handler.
|
||||
|
/// </summary>
|
||||
|
public static class OpenIddictServerEvents |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each HTTP request to determine if
|
||||
|
/// it should be handled by the OpenID Connect server middleware.
|
||||
|
/// </summary>
|
||||
|
public sealed class MatchEndpoint : OpenIddictServerEvent<MatchEndpointContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="MatchEndpoint"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public MatchEndpoint([NotNull] MatchEndpointContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the authorization endpoint to give the user code
|
||||
|
/// a chance to manually extract the authorization request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
public sealed class ExtractAuthorizationRequest : OpenIddictServerEvent<ExtractAuthorizationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractAuthorizationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractAuthorizationRequest([NotNull] ExtractAuthorizationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the configuration endpoint to give the user code
|
||||
|
/// a chance to manually extract the configuration request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
public sealed class ExtractConfigurationRequest : OpenIddictServerEvent<ExtractConfigurationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractConfigurationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractConfigurationRequest([NotNull] ExtractConfigurationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the cryptography endpoint to give the user code
|
||||
|
/// a chance to manually extract the cryptography request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
|
||||
|
public sealed class ExtractCryptographyRequest : OpenIddictServerEvent<ExtractCryptographyRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractCryptographyRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractCryptographyRequest([NotNull] ExtractCryptographyRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the introspection endpoint to give the user code
|
||||
|
/// a chance to manually extract the introspection request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
public sealed class ExtractIntrospectionRequest : OpenIddictServerEvent<ExtractIntrospectionRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractIntrospectionRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractIntrospectionRequest([NotNull] ExtractIntrospectionRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the logout endpoint to give the user code
|
||||
|
/// a chance to manually extract the logout request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
public sealed class ExtractLogoutRequest : OpenIddictServerEvent<ExtractLogoutRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractLogoutRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractLogoutRequest([NotNull] ExtractLogoutRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the revocation endpoint to give the user code
|
||||
|
/// a chance to manually extract the revocation request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
public sealed class ExtractRevocationRequest : OpenIddictServerEvent<ExtractRevocationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractRevocationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractRevocationRequest([NotNull] ExtractRevocationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the token endpoint to give the user code
|
||||
|
/// a chance to manually extract the token request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
public sealed class ExtractTokenRequest : OpenIddictServerEvent<ExtractTokenRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractTokenRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractTokenRequest([NotNull] ExtractTokenRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the userinfo endpoint to give the user code
|
||||
|
/// a chance to manually extract the userinfo request from the ambient HTTP context.
|
||||
|
/// </summary>
|
||||
|
public sealed class ExtractUserinfoRequest : OpenIddictServerEvent<ExtractUserinfoRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ExtractUserinfoRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ExtractUserinfoRequest([NotNull] ExtractUserinfoRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the authorization endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateAuthorizationRequest : OpenIddictServerEvent<ValidateAuthorizationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateAuthorizationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateAuthorizationRequest([NotNull] ValidateAuthorizationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the configuration endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateConfigurationRequest : OpenIddictServerEvent<ValidateConfigurationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateConfigurationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateConfigurationRequest([NotNull] ValidateConfigurationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the cryptography endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateCryptographyRequest : OpenIddictServerEvent<ValidateCryptographyRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateCryptographyRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateCryptographyRequest([NotNull] ValidateCryptographyRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the introspection endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateIntrospectionRequest : OpenIddictServerEvent<ValidateIntrospectionRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateIntrospectionRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the logout endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateLogoutRequest : OpenIddictServerEvent<ValidateLogoutRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateLogoutRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the revocation endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateRevocationRequest : OpenIddictServerEvent<ValidateRevocationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateRevocationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateRevocationRequest([NotNull] ValidateRevocationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the token endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateTokenRequest : OpenIddictServerEvent<ValidateTokenRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateTokenRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateTokenRequest([NotNull] ValidateTokenRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each request to the userinfo endpoint
|
||||
|
/// to determine if the request is valid and should continue to be processed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateUserinfoRequest : OpenIddictServerEvent<ValidateUserinfoRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateUserinfoRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateUserinfoRequest([NotNull] ValidateUserinfoRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated authorization request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleAuthorizationRequest : OpenIddictServerEvent<HandleAuthorizationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleAuthorizationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleAuthorizationRequest([NotNull] HandleAuthorizationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated configuration request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleConfigurationRequest : OpenIddictServerEvent<HandleConfigurationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleConfigurationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleConfigurationRequest([NotNull] HandleConfigurationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated cryptography request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleCryptographyRequest : OpenIddictServerEvent<HandleCryptographyRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleCryptographyRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleCryptographyRequest([NotNull] HandleCryptographyRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated introspection request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleIntrospectionRequest : OpenIddictServerEvent<HandleIntrospectionRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleIntrospectionRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated logout request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleLogoutRequest : OpenIddictServerEvent<HandleLogoutRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleLogoutRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleLogoutRequest([NotNull] HandleLogoutRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated revocation request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleRevocationRequest : OpenIddictServerEvent<HandleRevocationRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleRevocationRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleRevocationRequest([NotNull] HandleRevocationRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated token request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleTokenRequest : OpenIddictServerEvent<HandleTokenRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleTokenRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleTokenRequest([NotNull] HandleTokenRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called for each validated userinfo request
|
||||
|
/// to allow the user code to decide how the request should be handled.
|
||||
|
/// </summary>
|
||||
|
public sealed class HandleUserinfoRequest : OpenIddictServerEvent<HandleUserinfoRequestContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="HandleUserinfoRequest"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public HandleUserinfoRequest([NotNull] HandleUserinfoRequestContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when processing a challenge response.
|
||||
|
/// </summary>
|
||||
|
public sealed class ProcessChallengeResponse : OpenIddictServerEvent<ProcessChallengeResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ProcessChallengeResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ProcessChallengeResponse([NotNull] ProcessChallengeResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when processing a sign-in response.
|
||||
|
/// </summary>
|
||||
|
public sealed class ProcessSigninResponse : OpenIddictServerEvent<ProcessSigninResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ProcessSigninResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ProcessSigninResponse([NotNull] ProcessSigninResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when processing a sign-out response.
|
||||
|
/// </summary>
|
||||
|
public sealed class ProcessSignoutResponse : OpenIddictServerEvent<ProcessSignoutResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ProcessSignoutResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ProcessSignoutResponse([NotNull] ProcessSignoutResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the authorization response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyAuthorizationResponse : OpenIddictServerEvent<ApplyAuthorizationResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyAuthorizationResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyAuthorizationResponse([NotNull] ApplyAuthorizationResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the configuration response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyConfigurationResponse : OpenIddictServerEvent<ApplyConfigurationResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyConfigurationResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyConfigurationResponse([NotNull] ApplyConfigurationResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the cryptography response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyCryptographyResponse : OpenIddictServerEvent<ApplyCryptographyResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyCryptographyResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyCryptographyResponse([NotNull] ApplyCryptographyResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the introspection response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyIntrospectionResponse : OpenIddictServerEvent<ApplyIntrospectionResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyIntrospectionResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyIntrospectionResponse([NotNull] ApplyIntrospectionResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the logout response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyLogoutResponse : OpenIddictServerEvent<ApplyLogoutResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyLogoutResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyLogoutResponse([NotNull] ApplyLogoutResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the revocation response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyRevocationResponse : OpenIddictServerEvent<ApplyRevocationResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyRevocationResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyRevocationResponse([NotNull] ApplyRevocationResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the token response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyTokenResponse : OpenIddictServerEvent<ApplyTokenResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyTokenResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyTokenResponse([NotNull] ApplyTokenResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called before the userinfo response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyUserinfoResponse : OpenIddictServerEvent<ApplyUserinfoResponseContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyUserinfoResponse"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyUserinfoResponse([NotNull] ApplyUserinfoResponseContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when serializing an authorization code.
|
||||
|
/// </summary>
|
||||
|
public sealed class SerializeAuthorizationCode : OpenIddictServerEvent<SerializeAuthorizationCodeContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="SerializeAuthorizationCode"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public SerializeAuthorizationCode([NotNull] SerializeAuthorizationCodeContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when serializing an access token.
|
||||
|
/// </summary>
|
||||
|
public sealed class SerializeAccessToken : OpenIddictServerEvent<SerializeAccessTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="SerializeAccessToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public SerializeAccessToken([NotNull] SerializeAccessTokenContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when serializing an identity token.
|
||||
|
/// </summary>
|
||||
|
public sealed class SerializeIdentityToken : OpenIddictServerEvent<SerializeIdentityTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="SerializeIdentityToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public SerializeIdentityToken([NotNull] SerializeIdentityTokenContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when serializing a refresh token.
|
||||
|
/// </summary>
|
||||
|
public sealed class SerializeRefreshToken : OpenIddictServerEvent<SerializeRefreshTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="SerializeRefreshToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public SerializeRefreshToken([NotNull] SerializeRefreshTokenContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when deserializing an authorization code.
|
||||
|
/// </summary>
|
||||
|
public sealed class DeserializeAuthorizationCode : OpenIddictServerEvent<DeserializeAuthorizationCodeContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="DeserializeAuthorizationCode"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public DeserializeAuthorizationCode([NotNull] DeserializeAuthorizationCodeContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when deserializing an access token.
|
||||
|
/// </summary>
|
||||
|
public sealed class DeserializeAccessToken : OpenIddictServerEvent<DeserializeAccessTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="DeserializeAccessToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public DeserializeAccessToken([NotNull] DeserializeAccessTokenContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when deserializing an identity token.
|
||||
|
/// </summary>
|
||||
|
public sealed class DeserializeIdentityToken : OpenIddictServerEvent<DeserializeIdentityTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="DeserializeIdentityToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public DeserializeIdentityToken([NotNull] DeserializeIdentityTokenContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an event called when deserializing a refresh token.
|
||||
|
/// </summary>
|
||||
|
public sealed class DeserializeRefreshToken : OpenIddictServerEvent<DeserializeRefreshTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="DeserializeRefreshToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public DeserializeRefreshToken([NotNull] DeserializeRefreshTokenContext context) : base(context) { } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace OpenIddict.Validation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents an OpenIddict validation event.
|
||||
|
/// </summary>
|
||||
|
public interface IOpenIddictValidationEvent { } |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Validation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a handler able to process <typeparamref name="TEvent"/> events.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the events handled by this instance.</typeparam>
|
||||
|
public interface IOpenIddictValidationEventHandler<TEvent> where TEvent : class, IOpenIddictValidationEvent |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Processes the event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="notification">The event to process.</param>
|
||||
|
/// <param name="cancellationToken">
|
||||
|
/// The <see cref="CancellationToken"/> that can be used to abort the operation.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
|
||||
|
/// </returns>
|
||||
|
Task HandleAsync([NotNull] TEvent notification, CancellationToken cancellationToken); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Validation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Dispatches events by invoking the corresponding handlers.
|
||||
|
/// </summary>
|
||||
|
public interface IOpenIddictValidationEventService |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Publishes a new event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the event to publish.</typeparam>
|
||||
|
/// <param name="notification">The event to publish.</param>
|
||||
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
|
||||
|
/// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns>
|
||||
|
Task PublishAsync<TEvent>([NotNull] TEvent notification, CancellationToken cancellationToken = default) |
||||
|
where TEvent : class, IOpenIddictValidationEvent; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Validation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents an OpenIddict validation event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TContext">The type of the context instance associated with the event.</typeparam>
|
||||
|
public class OpenIddictValidationEvent<TContext> : IOpenIddictValidationEvent where TContext : class |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="OpenIddictValidationEvent{TContext}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the event.</param>
|
||||
|
public OpenIddictValidationEvent([NotNull] TContext context) |
||||
|
=> Context = context ?? throw new ArgumentNullException(nameof(context)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the context instance associated with the event.
|
||||
|
/// </summary>
|
||||
|
public TContext Context { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Validation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a handler able to process <typeparamref name="TEvent"/> events.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the events handled by this instance.</typeparam>
|
||||
|
public class OpenIddictValidationEventHandler<TEvent> : IOpenIddictValidationEventHandler<TEvent> |
||||
|
where TEvent : class, IOpenIddictValidationEvent |
||||
|
{ |
||||
|
private readonly Func<TEvent, CancellationToken, Task> _handler; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new event using the specified handler delegate.
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler">The event handler delegate</param>
|
||||
|
public OpenIddictValidationEventHandler([NotNull] Func<TEvent, CancellationToken, Task> handler) |
||||
|
=> _handler = handler ?? throw new ArgumentNullException(nameof(handler)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Processes the event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="notification">The event to process.</param>
|
||||
|
/// <param name="cancellationToken">
|
||||
|
/// The <see cref="CancellationToken"/> that can be used to abort the operation.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
|
||||
|
/// </returns>
|
||||
|
public Task HandleAsync(TEvent notification, CancellationToken cancellationToken) |
||||
|
{ |
||||
|
if (notification == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(notification)); |
||||
|
} |
||||
|
|
||||
|
if (cancellationToken.IsCancellationRequested) |
||||
|
{ |
||||
|
return Task.FromCanceled(cancellationToken); |
||||
|
} |
||||
|
|
||||
|
return _handler.Invoke(notification, cancellationToken); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
namespace OpenIddict.Validation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Dispatches notifications by invoking the corresponding handlers.
|
||||
|
/// </summary>
|
||||
|
public class OpenIddictValidationEventService : IOpenIddictValidationEventService |
||||
|
{ |
||||
|
private readonly IServiceProvider _provider; |
||||
|
|
||||
|
public OpenIddictValidationEventService([NotNull] IServiceProvider provider) |
||||
|
{ |
||||
|
_provider = provider; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Publishes a new event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEvent">The type of the event to publish.</typeparam>
|
||||
|
/// <param name="notification">The event to publish.</param>
|
||||
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
|
||||
|
/// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns>
|
||||
|
public async Task PublishAsync<TEvent>([NotNull] TEvent notification, CancellationToken cancellationToken = default) |
||||
|
where TEvent : class, IOpenIddictValidationEvent |
||||
|
{ |
||||
|
if (notification == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(notification)); |
||||
|
} |
||||
|
|
||||
|
foreach (var handler in _provider.GetServices<IOpenIddictValidationEventHandler<TEvent>>()) |
||||
|
{ |
||||
|
cancellationToken.ThrowIfCancellationRequested(); |
||||
|
|
||||
|
await handler.HandleAsync(notification, cancellationToken); |
||||
|
|
||||
|
// Note: the following logic determines whether next handlers should be invoked
|
||||
|
// depending on whether the underlying event context was substantially updated.
|
||||
|
switch (notification) |
||||
|
{ |
||||
|
case OpenIddictValidationEvents.ApplyChallenge value when value.Context.Handled: return; |
||||
|
|
||||
|
case OpenIddictValidationEvents.CreateTicket value when value.Context.Result != null: return; |
||||
|
case OpenIddictValidationEvents.CreateTicket value when value.Context.Principal == null: return; |
||||
|
|
||||
|
case OpenIddictValidationEvents.DecryptToken value when value.Context.Result != null: return; |
||||
|
case OpenIddictValidationEvents.DecryptToken value when value.Context.Principal != null: return; |
||||
|
|
||||
|
case OpenIddictValidationEvents.RetrieveToken value when value.Context.Result != null: return; |
||||
|
case OpenIddictValidationEvents.RetrieveToken value when value.Context.Principal != null: return; |
||||
|
|
||||
|
case OpenIddictValidationEvents.ValidateToken value when value.Context.Result != null: return; |
||||
|
case OpenIddictValidationEvents.ValidateToken value when value.Context.Principal == null: return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
using AspNet.Security.OAuth.Validation; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace OpenIddict.Validation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Contains common events used by the OpenIddict validation handler.
|
||||
|
/// </summary>
|
||||
|
public static class OpenIddictValidationEvents |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Invoked when a challenge response is returned to the caller.
|
||||
|
/// </summary>
|
||||
|
public sealed class ApplyChallenge : OpenIddictValidationEvent<ApplyChallengeContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ApplyChallenge"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ApplyChallenge([NotNull] ApplyChallengeContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Invoked when a ticket is to be created from an introspection response.
|
||||
|
/// </summary>
|
||||
|
public sealed class CreateTicket : OpenIddictValidationEvent<CreateTicketContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="CreateTicket"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public CreateTicket([NotNull] CreateTicketContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Invoked when a token is to be decrypted.
|
||||
|
/// </summary>
|
||||
|
public sealed class DecryptToken : OpenIddictValidationEvent<DecryptTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="DecryptToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public DecryptToken([NotNull] DecryptTokenContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Invoked when a token is to be parsed from a newly-received request.
|
||||
|
/// </summary>
|
||||
|
public sealed class RetrieveToken : OpenIddictValidationEvent<RetrieveTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="RetrieveToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public RetrieveToken([NotNull] RetrieveTokenContext context) : base(context) { } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Invoked when a token is to be validated, before final processing.
|
||||
|
/// </summary>
|
||||
|
public sealed class ValidateToken : OpenIddictValidationEvent<ValidateTokenContext> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ValidateToken"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">The context instance associated with the notification.</param>
|
||||
|
public ValidateToken([NotNull] ValidateTokenContext context) : base(context) { } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,110 +0,0 @@ |
|||||
/* |
|
||||
* 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.Threading.Tasks; |
|
||||
using AspNet.Security.OAuth.Validation; |
|
||||
using AspNet.Security.OpenIdConnect.Client; |
|
||||
using Microsoft.AspNetCore.Authentication; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.AspNetCore.TestHost; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using Xunit; |
|
||||
|
|
||||
namespace OpenIddict.Validation.Tests |
|
||||
{ |
|
||||
public class OpenIddictValidationInitializerTests |
|
||||
{ |
|
||||
[Fact] |
|
||||
public async Task PostConfigure_ThrowsAnExceptionWhenApplicationEventsTypeAndInstanceAreProvided() |
|
||||
{ |
|
||||
// Arrange
|
|
||||
var server = CreateAuthorizationServer(builder => |
|
||||
{ |
|
||||
builder.Configure(options => |
|
||||
{ |
|
||||
options.ApplicationEvents = new OAuthValidationEvents(); |
|
||||
options.ApplicationEventsType = typeof(OAuthValidationEvents); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
var client = new OpenIdConnectClient(server.CreateClient()); |
|
||||
|
|
||||
// Act and assert
|
|
||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(delegate |
|
||||
{ |
|
||||
return client.GetAsync("/"); |
|
||||
}); |
|
||||
|
|
||||
// Assert
|
|
||||
Assert.Equal("Application events cannot be registered when a type is specified.", exception.Message); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public async Task PostConfigure_ThrowsAnExceptionForInvalidApplicationEventsType() |
|
||||
{ |
|
||||
// Arrange
|
|
||||
var server = CreateAuthorizationServer(builder => |
|
||||
{ |
|
||||
builder.Configure(options => options.ApplicationEventsType = typeof(object)); |
|
||||
}); |
|
||||
|
|
||||
var client = new OpenIdConnectClient(server.CreateClient()); |
|
||||
|
|
||||
// Act and assert
|
|
||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(delegate |
|
||||
{ |
|
||||
return client.GetAsync("/"); |
|
||||
}); |
|
||||
|
|
||||
// Assert
|
|
||||
Assert.Equal("Application events must inherit from OAuthValidationEvents.", exception.Message); |
|
||||
} |
|
||||
|
|
||||
private static TestServer CreateAuthorizationServer(Action<OpenIddictValidationBuilder> configuration = null) |
|
||||
{ |
|
||||
var builder = new WebHostBuilder(); |
|
||||
|
|
||||
builder.UseEnvironment("Testing"); |
|
||||
|
|
||||
builder.ConfigureLogging(options => options.AddDebug()); |
|
||||
|
|
||||
builder.ConfigureServices(services => |
|
||||
{ |
|
||||
services.AddAuthentication(); |
|
||||
services.AddOptions(); |
|
||||
services.AddDistributedMemoryCache(); |
|
||||
|
|
||||
services.AddOpenIddict() |
|
||||
.AddCore(options => |
|
||||
{ |
|
||||
options.SetDefaultApplicationEntity<OpenIddictApplication>() |
|
||||
.SetDefaultAuthorizationEntity<OpenIddictAuthorization>() |
|
||||
.SetDefaultScopeEntity<OpenIddictScope>() |
|
||||
.SetDefaultTokenEntity<OpenIddictToken>(); |
|
||||
}) |
|
||||
|
|
||||
.AddValidation(options => configuration?.Invoke(options)); |
|
||||
}); |
|
||||
|
|
||||
builder.Configure(app => |
|
||||
{ |
|
||||
app.UseAuthentication(); |
|
||||
|
|
||||
app.Run(context => context.ChallengeAsync(OpenIddictValidationDefaults.AuthenticationScheme)); |
|
||||
}); |
|
||||
|
|
||||
return new TestServer(builder); |
|
||||
} |
|
||||
|
|
||||
public class OpenIddictApplication { } |
|
||||
public class OpenIddictAuthorization { } |
|
||||
public class OpenIddictScope { } |
|
||||
public class OpenIddictToken { } |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue