Browse Source

Split request caching into 2 separate options

pull/847/head
Kévin Chalet 6 years ago
parent
commit
af1fb2e890
  1. 45
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreBuilder.cs
  2. 3
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreExtensions.cs
  3. 48
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlerFilters.cs
  4. 8
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs
  5. 8
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs
  6. 28
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreOptions.cs
  7. 41
      src/OpenIddict.Server.Owin/OpenIddictServerOwinBuilder.cs
  8. 3
      src/OpenIddict.Server.Owin/OpenIddictServerOwinExtensions.cs
  9. 61
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlerFilters.cs
  10. 8
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs
  11. 8
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs
  12. 26
      src/OpenIddict.Server.Owin/OpenIddictServerOwinOptions.cs

45
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreBuilder.cs

@ -120,39 +120,62 @@ namespace Microsoft.Extensions.DependencyInjection
=> Configure(options => options.EnableVerificationEndpointPassthrough = true);
/// <summary>
/// Enables request caching, so that both authorization and logout requests
/// Enables authorization endpoint caching, so that authorization requests
/// are automatically stored in the distributed cache, which allows flowing
/// large payloads across requests. Enabling this option is recommended
/// when using external authentication providers or when large GET or POST
/// OpenID Connect authorization requests support is required.
/// </summary>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder EnableRequestCaching()
=> Configure(options => options.EnableRequestCaching = true);
public OpenIddictServerAspNetCoreBuilder EnableAuthorizationEndpointCaching()
=> Configure(options => options.EnableAuthorizationEndpointCaching = true);
/// <summary>
/// Enables status code pages integration support. Once enabled, errors generated
/// by the interactive authorization and logout endpoints can be handled by ASP.NET Core.
/// Enables logout endpoint caching, so that logout requests
/// are automatically stored in the distributed cache.
/// </summary>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder EnableLogoutEndpointCaching()
=> Configure(options => options.EnableLogoutEndpointCaching = true);
/// <summary>
/// Enables status code pages integration support. Once enabled, errors
/// generated by the interactive endpoints can be handled by ASP.NET Core.
/// </summary>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder EnableStatusCodePagesIntegration()
=> Configure(options => options.EnableStatusCodePagesIntegration = true);
/// <summary>
/// Sets the caching policy used to determine how long the authorization and
/// end session requests should be cached by the distributed cache implementation.
/// Note: the specified policy is only used when request caching is explicitly enabled.
/// Sets the caching policy used by the authorization endpoint.
/// Note: the specified policy is only used when caching is explicitly enabled.
/// </summary>
/// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder SetAuthorizationEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy)
{
if (policy == null)
{
throw new ArgumentNullException(nameof(policy));
}
return Configure(options => options.AuthorizationEndpointCachingPolicy = policy);
}
/// <summary>
/// Sets the caching policy used by the logout endpoint.
/// Note: the specified policy is only used when caching is explicitly enabled.
/// </summary>
/// <param name="policy">The request caching policy.</param>
/// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder SetRequestCachingPolicy([NotNull] DistributedCacheEntryOptions policy)
public OpenIddictServerAspNetCoreBuilder SetLogoutEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy)
{
if (policy == null)
{
throw new ArgumentNullException(nameof(policy));
}
return Configure(options => options.RequestCachingPolicy = policy);
return Configure(options => options.LogoutEndpointCachingPolicy = policy);
}
/// <summary>

3
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreExtensions.cs

@ -44,12 +44,13 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Services.TryAdd(DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));
// Register the built-in filters used by the default OpenIddict ASP.NET Core server event handlers.
builder.Services.TryAddSingleton<RequireAuthorizationEndpointCachingEnabled>();
builder.Services.TryAddSingleton<RequireAuthorizationEndpointPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireErrorPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireHttpRequest>();
builder.Services.TryAddSingleton<RequireLogoutEndpointCachingEnabled>();
builder.Services.TryAddSingleton<RequireLogoutEndpointPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireTransportSecurityRequirementEnabled>();
builder.Services.TryAddSingleton<RequireRequestCachingEnabled>();
builder.Services.TryAddSingleton<RequireStatusCodePagesIntegrationEnabled>();
builder.Services.TryAddSingleton<RequireTokenEndpointPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireUserinfoEndpointPassthroughEnabled>();

48
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlerFilters.cs

@ -20,6 +20,27 @@ namespace OpenIddict.Server.AspNetCore
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static class OpenIddictServerAspNetCoreHandlerFilters
{
/// <summary>
/// Represents a filter that excludes the associated handlers if authorization endpoint caching was not enabled.
/// </summary>
public class RequireAuthorizationEndpointCachingEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireAuthorizationEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(_options.CurrentValue.EnableAuthorizationEndpointCaching);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if the
/// pass-through mode was not enabled for the authorization endpoint.
@ -78,15 +99,15 @@ namespace OpenIddict.Server.AspNetCore
return new ValueTask<bool>(context.Transaction.GetHttpRequest() != null);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if the
/// pass-through mode was not enabled for the logout endpoint.
/// Represents a filter that excludes the associated handlers if logout endpoint caching was not enabled.
/// </summary>
public class RequireLogoutEndpointPassthroughEnabled : IOpenIddictServerHandlerFilter<BaseContext>
public class RequireLogoutEndpointCachingEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireLogoutEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
public RequireLogoutEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
@ -96,18 +117,19 @@ namespace OpenIddict.Server.AspNetCore
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(_options.CurrentValue.EnableLogoutEndpointPassthrough);
return new ValueTask<bool>(_options.CurrentValue.EnableLogoutEndpointCaching);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if the HTTPS requirement was disabled.
/// Represents a filter that excludes the associated handlers if the
/// pass-through mode was not enabled for the logout endpoint.
/// </summary>
public class RequireTransportSecurityRequirementEnabled : IOpenIddictServerHandlerFilter<BaseContext>
public class RequireLogoutEndpointPassthroughEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireTransportSecurityRequirementEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
public RequireLogoutEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
@ -117,18 +139,18 @@ namespace OpenIddict.Server.AspNetCore
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(!_options.CurrentValue.DisableTransportSecurityRequirement);
return new ValueTask<bool>(_options.CurrentValue.EnableLogoutEndpointPassthrough);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if request caching was not enabled.
/// Represents a filter that excludes the associated handlers if the HTTPS requirement was disabled.
/// </summary>
public class RequireRequestCachingEnabled : IOpenIddictServerHandlerFilter<BaseContext>
public class RequireTransportSecurityRequirementEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireRequestCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
public RequireTransportSecurityRequirementEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
@ -138,7 +160,7 @@ namespace OpenIddict.Server.AspNetCore
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(_options.CurrentValue.EnableRequestCaching);
return new ValueTask<bool>(!_options.CurrentValue.DisableTransportSecurityRequirement);
}
}

8
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs

@ -81,7 +81,7 @@ namespace OpenIddict.Server.AspNetCore
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractAuthorizationRequestContext>()
.AddFilter<RequireHttpRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireAuthorizationEndpointCachingEnabled>()
.UseSingletonHandler<RestoreCachedRequestParameters>()
.SetOrder(ExtractGetOrPostRequest<ExtractAuthorizationRequestContext>.Descriptor.Order + 1_000)
.Build();
@ -168,7 +168,7 @@ namespace OpenIddict.Server.AspNetCore
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractAuthorizationRequestContext>()
.AddFilter<RequireHttpRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireAuthorizationEndpointCachingEnabled>()
.UseSingletonHandler<CacheRequestParameters>()
.SetOrder(RestoreCachedRequestParameters.Descriptor.Order + 1_000)
.Build();
@ -228,7 +228,7 @@ namespace OpenIddict.Server.AspNetCore
// Note: the cache key is always prefixed with a specific marker
// to avoid collisions with the other types of cached payloads.
await _cache.SetAsync(Cache.AuthorizationRequest + context.Request.RequestId,
stream.ToArray(), _options.CurrentValue.RequestCachingPolicy);
stream.ToArray(), _options.CurrentValue.AuthorizationEndpointCachingPolicy);
// Create a new GET authorization request containing only the request_id parameter.
var address = QueryHelpers.AddQueryString(
@ -267,7 +267,7 @@ namespace OpenIddict.Server.AspNetCore
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ApplyAuthorizationResponseContext>()
.AddFilter<RequireHttpRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireAuthorizationEndpointCachingEnabled>()
.UseSingletonHandler<RemoveCachedRequest>()
.SetOrder(ProcessFormPostResponse.Descriptor.Order - 1_000)
.Build();

8
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs

@ -80,7 +80,7 @@ namespace OpenIddict.Server.AspNetCore
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractLogoutRequestContext>()
.AddFilter<RequireHttpRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireLogoutEndpointCachingEnabled>()
.UseSingletonHandler<RestoreCachedRequestParameters>()
.SetOrder(ExtractGetOrPostRequest<ExtractLogoutRequestContext>.Descriptor.Order + 1_000)
.Build();
@ -167,7 +167,7 @@ namespace OpenIddict.Server.AspNetCore
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractLogoutRequestContext>()
.AddFilter<RequireHttpRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireLogoutEndpointCachingEnabled>()
.UseSingletonHandler<CacheRequestParameters>()
.SetOrder(RestoreCachedRequestParameters.Descriptor.Order + 1_000)
.Build();
@ -227,7 +227,7 @@ namespace OpenIddict.Server.AspNetCore
// Note: the cache key is always prefixed with a specific marker
// to avoid collisions with the other types of cached payloads.
await _cache.SetAsync(Cache.LogoutRequest + context.Request.RequestId,
stream.ToArray(), _options.CurrentValue.RequestCachingPolicy);
stream.ToArray(), _options.CurrentValue.LogoutEndpointCachingPolicy);
// Create a new GET logout request containing only the request_id parameter.
var address = QueryHelpers.AddQueryString(
@ -266,7 +266,7 @@ namespace OpenIddict.Server.AspNetCore
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ApplyLogoutResponseContext>()
.AddFilter<RequireHttpRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireLogoutEndpointCachingEnabled>()
.UseSingletonHandler<RemoveCachedRequest>()
.SetOrder(ProcessQueryResponse.Descriptor.Order - 1_000)
.Build();

28
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreOptions.cs

@ -72,26 +72,40 @@ namespace OpenIddict.Server.AspNetCore
public bool EnableVerificationEndpointPassthrough { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether request caching should be enabled.
/// When enabled, both authorization and logout requests are automatically stored
/// Gets or sets a boolean indicating whether requests received by the authorization endpoint
/// should be cached. When enabled, authorization requests are automatically stored
/// in the distributed cache, which allows flowing large payloads across requests.
/// Enabling this option is recommended when using external authentication providers
/// or when large GET or POST OpenID Connect authorization requests support is required.
/// </summary>
public bool EnableRequestCaching { get; set; }
public bool EnableAuthorizationEndpointCaching { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether requests received by the logout endpoint should be cached.
/// When enabled, authorization requests are automatically stored in the distributed cache.
/// </summary>
public bool EnableLogoutEndpointCaching { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether integration with the status code pages
/// middleware should be enabled or not. Once enabled, errors generated by the OpenIddict
/// interactive authorization and logout endpoints can be handled by ASP.NET Core.
/// interactive endpoints (e.g authorization or logout) can be handled by ASP.NET Core.
/// </summary>
public bool EnableStatusCodePagesIntegration { get; set; }
/// <summary>
/// Gets or sets the caching policy used to determine how long the authorization
/// and end session requests should be cached by the distributed cache implementation.
/// Gets or sets the caching policy used by the authorization endpoint.
/// </summary>
public DistributedCacheEntryOptions AuthorizationEndpointCachingPolicy { get; set; } = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1),
SlidingExpiration = TimeSpan.FromMinutes(30)
};
/// <summary>
/// Gets or sets the caching policy used by the logout endpoint.
/// </summary>
public DistributedCacheEntryOptions RequestCachingPolicy { get; set; } = new DistributedCacheEntryOptions
public DistributedCacheEntryOptions LogoutEndpointCachingPolicy { get; set; } = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1),
SlidingExpiration = TimeSpan.FromMinutes(30)

41
src/OpenIddict.Server.Owin/OpenIddictServerOwinBuilder.cs

@ -120,31 +120,54 @@ namespace Microsoft.Extensions.DependencyInjection
=> Configure(options => options.EnableVerificationEndpointPassthrough = true);
/// <summary>
/// Enables request caching, so that both authorization and logout requests
/// Enables authorization endpoint caching, so that authorization requests
/// are automatically stored in the distributed cache, which allows flowing
/// large payloads across requests. Enabling this option is recommended
/// when using external authentication providers or when large GET or POST
/// OpenID Connect authorization requests support is required.
/// </summary>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder EnableRequestCaching()
=> Configure(options => options.EnableRequestCaching = true);
public OpenIddictServerOwinBuilder EnableAuthorizationEndpointCaching()
=> Configure(options => options.EnableAuthorizationEndpointCaching = true);
/// <summary>
/// Sets the caching policy used to determine how long the authorization and
/// end session requests should be cached by the distributed cache implementation.
/// Note: the specified policy is only used when request caching is explicitly enabled.
/// Enables logout endpoint caching, so that logout requests
/// are automatically stored in the distributed cache.
/// </summary>
/// <param name="policy">The request caching policy.</param>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder SetRequestCachingPolicy([NotNull] DistributedCacheEntryOptions policy)
public OpenIddictServerOwinBuilder EnableLogoutEndpointCaching()
=> Configure(options => options.EnableLogoutEndpointCaching = true);
/// <summary>
/// Sets the caching policy used by the authorization endpoint.
/// Note: the specified policy is only used when caching is explicitly enabled.
/// </summary>
/// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder SetAuthorizationEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy)
{
if (policy == null)
{
throw new ArgumentNullException(nameof(policy));
}
return Configure(options => options.AuthorizationEndpointCachingPolicy = policy);
}
/// <summary>
/// Sets the caching policy used by the logout endpoint.
/// Note: the specified policy is only used when caching is explicitly enabled.
/// </summary>
/// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder SetLogoutEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy)
{
if (policy == null)
{
throw new ArgumentNullException(nameof(policy));
}
return Configure(options => options.RequestCachingPolicy = policy);
return Configure(options => options.LogoutEndpointCachingPolicy = policy);
}
/// <summary>

3
src/OpenIddict.Server.Owin/OpenIddictServerOwinExtensions.cs

@ -46,12 +46,13 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Services.TryAdd(DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));
// Register the built-in filters used by the default OpenIddict OWIN server event handlers.
builder.Services.TryAddSingleton<RequireAuthorizationEndpointCachingEnabled>();
builder.Services.TryAddSingleton<RequireAuthorizationEndpointPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireErrorPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireLogoutEndpointCachingEnabled>();
builder.Services.TryAddSingleton<RequireLogoutEndpointPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireTransportSecurityRequirementEnabled>();
builder.Services.TryAddSingleton<RequireOwinRequest>();
builder.Services.TryAddSingleton<RequireRequestCachingEnabled>();
builder.Services.TryAddSingleton<RequireTokenEndpointPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireUserinfoEndpointPassthroughEnabled>();
builder.Services.TryAddSingleton<RequireVerificationEndpointPassthroughEnabled>();

61
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlerFilters.cs

@ -18,6 +18,27 @@ namespace OpenIddict.Server.Owin
/// </summary>
public static class OpenIddictServerOwinHandlerFilters
{
/// <summary>
/// Represents a filter that excludes the associated handlers if authorization endpoint caching was not enabled.
/// </summary>
public class RequireAuthorizationEndpointCachingEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireAuthorizationEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(_options.CurrentValue.EnableAuthorizationEndpointCaching);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if the
/// pass-through mode was not enabled for the authorization endpoint.
@ -62,14 +83,13 @@ namespace OpenIddict.Server.Owin
}
/// <summary>
/// Represents a filter that excludes the associated handlers if the
/// pass-through mode was not enabled for the logout endpoint.
/// Represents a filter that excludes the associated handlers if logout endpoint caching was not enabled.
/// </summary>
public class RequireLogoutEndpointPassthroughEnabled : IOpenIddictServerHandlerFilter<BaseContext>
public class RequireLogoutEndpointCachingEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireLogoutEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
public RequireLogoutEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
@ -79,15 +99,21 @@ namespace OpenIddict.Server.Owin
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(_options.CurrentValue.EnableLogoutEndpointPassthrough);
return new ValueTask<bool>(_options.CurrentValue.EnableLogoutEndpointCaching);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if no OWIN request can be found.
/// Represents a filter that excludes the associated handlers if the
/// pass-through mode was not enabled for the logout endpoint.
/// </summary>
public class RequireOwinRequest : IOpenIddictServerHandlerFilter<BaseContext>
public class RequireLogoutEndpointPassthroughEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireLogoutEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
{
if (context == null)
@ -95,20 +121,15 @@ namespace OpenIddict.Server.Owin
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(context.Transaction.GetOwinRequest() != null);
return new ValueTask<bool>(_options.CurrentValue.EnableLogoutEndpointPassthrough);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if the HTTPS requirement was disabled.
/// Represents a filter that excludes the associated handlers if no OWIN request can be found.
/// </summary>
public class RequireTransportSecurityRequirementEnabled : IOpenIddictServerHandlerFilter<BaseContext>
public class RequireOwinRequest : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireTransportSecurityRequirementEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
{
if (context == null)
@ -116,18 +137,18 @@ namespace OpenIddict.Server.Owin
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(!_options.CurrentValue.DisableTransportSecurityRequirement);
return new ValueTask<bool>(context.Transaction.GetOwinRequest() != null);
}
}
/// <summary>
/// Represents a filter that excludes the associated handlers if request caching was not enabled.
/// Represents a filter that excludes the associated handlers if the HTTPS requirement was disabled.
/// </summary>
public class RequireRequestCachingEnabled : IOpenIddictServerHandlerFilter<BaseContext>
public class RequireTransportSecurityRequirementEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireRequestCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
public RequireTransportSecurityRequirementEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
@ -137,7 +158,7 @@ namespace OpenIddict.Server.Owin
throw new ArgumentNullException(nameof(context));
}
return new ValueTask<bool>(_options.CurrentValue.EnableRequestCaching);
return new ValueTask<bool>(!_options.CurrentValue.DisableTransportSecurityRequirement);
}
}

8
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs

@ -80,7 +80,7 @@ namespace OpenIddict.Server.Owin
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractAuthorizationRequestContext>()
.AddFilter<RequireOwinRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireAuthorizationEndpointCachingEnabled>()
.UseSingletonHandler<RestoreCachedRequestParameters>()
.SetOrder(ExtractGetOrPostRequest<ExtractAuthorizationRequestContext>.Descriptor.Order + 1_000)
.Build();
@ -167,7 +167,7 @@ namespace OpenIddict.Server.Owin
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractAuthorizationRequestContext>()
.AddFilter<RequireOwinRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireAuthorizationEndpointCachingEnabled>()
.UseSingletonHandler<CacheRequestParameters>()
.SetOrder(RestoreCachedRequestParameters.Descriptor.Order + 1_000)
.Build();
@ -222,7 +222,7 @@ namespace OpenIddict.Server.Owin
// Note: the cache key is always prefixed with a specific marker
// to avoid collisions with the other types of cached payloads.
await _cache.SetAsync(Cache.AuthorizationRequest + context.Request.RequestId,
stream.ToArray(), _options.CurrentValue.RequestCachingPolicy);
stream.ToArray(), _options.CurrentValue.AuthorizationEndpointCachingPolicy);
// Create a new GET authorization request containing only the request_id parameter.
var address = WebUtilities.AddQueryString(
@ -261,7 +261,7 @@ namespace OpenIddict.Server.Owin
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ApplyAuthorizationResponseContext>()
.AddFilter<RequireOwinRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireAuthorizationEndpointCachingEnabled>()
.UseSingletonHandler<RemoveCachedRequest>()
.SetOrder(ProcessFormPostResponse.Descriptor.Order - 1_000)
.Build();

8
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs

@ -79,7 +79,7 @@ namespace OpenIddict.Server.Owin
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractLogoutRequestContext>()
.AddFilter<RequireOwinRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireLogoutEndpointCachingEnabled>()
.UseSingletonHandler<RestoreCachedRequestParameters>()
.SetOrder(ExtractGetOrPostRequest<ExtractLogoutRequestContext>.Descriptor.Order + 1_000)
.Build();
@ -166,7 +166,7 @@ namespace OpenIddict.Server.Owin
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ExtractLogoutRequestContext>()
.AddFilter<RequireOwinRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireLogoutEndpointCachingEnabled>()
.UseSingletonHandler<CacheRequestParameters>()
.SetOrder(RestoreCachedRequestParameters.Descriptor.Order + 1_000)
.Build();
@ -221,7 +221,7 @@ namespace OpenIddict.Server.Owin
// Note: the cache key is always prefixed with a specific marker
// to avoid collisions with the other types of cached payloads.
await _cache.SetAsync(Cache.LogoutRequest + context.Request.RequestId,
stream.ToArray(), _options.CurrentValue.RequestCachingPolicy);
stream.ToArray(), _options.CurrentValue.LogoutEndpointCachingPolicy);
// Create a new GET logout request containing only the request_id parameter.
var address = WebUtilities.AddQueryString(
@ -260,7 +260,7 @@ namespace OpenIddict.Server.Owin
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<ApplyLogoutResponseContext>()
.AddFilter<RequireOwinRequest>()
.AddFilter<RequireRequestCachingEnabled>()
.AddFilter<RequireLogoutEndpointCachingEnabled>()
.UseSingletonHandler<RemoveCachedRequest>()
.SetOrder(ProcessQueryResponse.Descriptor.Order - 1_000)
.Build();

26
src/OpenIddict.Server.Owin/OpenIddictServerOwinOptions.cs

@ -79,19 +79,33 @@ namespace OpenIddict.Server.Owin
public bool EnableVerificationEndpointPassthrough { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether request caching should be enabled.
/// When enabled, both authorization and logout requests are automatically stored
/// Gets or sets a boolean indicating whether requests received by the authorization endpoint
/// should be cached. When enabled, authorization requests are automatically stored
/// in the distributed cache, which allows flowing large payloads across requests.
/// Enabling this option is recommended when using external authentication providers
/// or when large GET or POST OpenID Connect authorization requests support is required.
/// </summary>
public bool EnableRequestCaching { get; set; }
public bool EnableAuthorizationEndpointCaching { get; set; }
/// <summary>
/// Gets or sets the caching policy used to determine how long the authorization
/// and end session requests should be cached by the distributed cache implementation.
/// Gets or sets a boolean indicating whether requests received by the logout endpoint should be cached.
/// When enabled, authorization requests are automatically stored in the distributed cache.
/// </summary>
public DistributedCacheEntryOptions RequestCachingPolicy { get; set; } = new DistributedCacheEntryOptions
public bool EnableLogoutEndpointCaching { get; set; }
/// <summary>
/// Gets or sets the caching policy used by the authorization endpoint.
/// </summary>
public DistributedCacheEntryOptions AuthorizationEndpointCachingPolicy { get; set; } = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1),
SlidingExpiration = TimeSpan.FromMinutes(30)
};
/// <summary>
/// Gets or sets the caching policy used by the logout endpoint.
/// </summary>
public DistributedCacheEntryOptions LogoutEndpointCachingPolicy { get; set; } = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1),
SlidingExpiration = TimeSpan.FromMinutes(30)

Loading…
Cancel
Save