Browse Source

Update the System.Net.Http integrations to support sending a contact address via the Form HTTP header

pull/1627/head
Kévin Chalet 4 years ago
parent
commit
6f5c509b3f
  1. 37
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpBuilder.cs
  2. 2
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Discovery.cs
  3. 1
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs
  4. 1
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs
  5. 42
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs
  6. 9
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpOptions.cs
  7. 39
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpBuilder.cs
  8. 2
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Discovery.cs
  9. 1
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Introspection.cs
  10. 42
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
  11. 9
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpOptions.cs

37
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpBuilder.cs

@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Net.Http.Headers;
using System.Net.Mail;
using System.Reflection;
using OpenIddict.Client.SystemNetHttp;
using Polly;
@ -48,6 +49,38 @@ public sealed class OpenIddictClientSystemNetHttpBuilder
return this;
}
/// <summary>
/// Sets the contact address used in the "From" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="address">The mail address.</param>
/// <returns>The <see cref="OpenIddictClientSystemNetHttpBuilder"/> instance.</returns>
public OpenIddictClientSystemNetHttpBuilder SetContactAddress(MailAddress address)
{
if (address is null)
{
throw new ArgumentNullException(nameof(address));
}
return Configure(options => options.ContactAddress = address);
}
/// <summary>
/// Sets the contact address used in the "From" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="address">The mail address.</param>
/// <returns>The <see cref="OpenIddictClientSystemNetHttpBuilder"/> instance.</returns>
public OpenIddictClientSystemNetHttpBuilder SetContactAddress(string address)
{
if (string.IsNullOrEmpty(address))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0366), nameof(address));
}
return SetContactAddress(new MailAddress(address));
}
/// <summary>
/// Replaces the default HTTP error policy used by the OpenIddict client services.
/// </summary>
@ -64,7 +97,7 @@ public sealed class OpenIddictClientSystemNetHttpBuilder
}
/// <summary>
/// Sets the product information used in the user agent header that is attached
/// Sets the product information used in the "User-Agent" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="information">The product information.</param>
@ -80,7 +113,7 @@ public sealed class OpenIddictClientSystemNetHttpBuilder
}
/// <summary>
/// Sets the product information used in the user agent header that is attached
/// Sets the product information used in the "User-Agent" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="name">The product name.</param>

2
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Discovery.cs

@ -19,6 +19,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
PrepareGetHttpRequest<PrepareConfigurationRequestContext>.Descriptor,
AttachJsonAcceptHeaders<PrepareConfigurationRequestContext>.Descriptor,
AttachUserAgentHeader<PrepareConfigurationRequestContext>.Descriptor,
AttachFromHeader<PrepareConfigurationRequestContext>.Descriptor,
AttachQueryStringParameters<PrepareConfigurationRequestContext>.Descriptor,
SendHttpRequest<ApplyConfigurationRequestContext>.Descriptor,
DisposeHttpRequest<ApplyConfigurationRequestContext>.Descriptor,
@ -38,6 +39,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
PrepareGetHttpRequest<PrepareCryptographyRequestContext>.Descriptor,
AttachJsonAcceptHeaders<PrepareCryptographyRequestContext>.Descriptor,
AttachUserAgentHeader<PrepareCryptographyRequestContext>.Descriptor,
AttachFromHeader<PrepareCryptographyRequestContext>.Descriptor,
AttachQueryStringParameters<PrepareCryptographyRequestContext>.Descriptor,
SendHttpRequest<ApplyCryptographyRequestContext>.Descriptor,
DisposeHttpRequest<ApplyCryptographyRequestContext>.Descriptor,

1
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs

@ -22,6 +22,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
PreparePostHttpRequest<PrepareTokenRequestContext>.Descriptor,
AttachJsonAcceptHeaders<PrepareTokenRequestContext>.Descriptor,
AttachUserAgentHeader<PrepareTokenRequestContext>.Descriptor,
AttachFromHeader<PrepareTokenRequestContext>.Descriptor,
AttachBasicAuthenticationCredentials.Descriptor,
AttachFormParameters<PrepareTokenRequestContext>.Descriptor,
SendHttpRequest<ApplyTokenRequestContext>.Descriptor,

1
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs

@ -22,6 +22,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
PrepareGetHttpRequest<PrepareUserinfoRequestContext>.Descriptor,
AttachJsonAcceptHeaders<PrepareUserinfoRequestContext>.Descriptor,
AttachUserAgentHeader<PrepareUserinfoRequestContext>.Descriptor,
AttachFromHeader<PrepareUserinfoRequestContext>.Descriptor,
AttachBearerAccessToken.Descriptor,
AttachQueryStringParameters<PrepareUserinfoRequestContext>.Descriptor,
SendHttpRequest<ApplyUserinfoRequestContext>.Descriptor,

42
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs

@ -9,6 +9,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.IO.Compression;
using System.Net.Http.Headers;
using System.Net.Mail;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
@ -185,6 +186,47 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
}
}
/// <summary>
/// Contains the logic responsible for attaching the contact address to the HTTP request.
/// </summary>
public sealed class AttachFromHeader<TContext> : IOpenIddictClientHandler<TContext> where TContext : BaseExternalContext
{
private readonly IOptionsMonitor<OpenIddictClientSystemNetHttpOptions> _options;
public AttachFromHeader(IOptionsMonitor<OpenIddictClientSystemNetHttpOptions> options)
=> _options = options ?? throw new ArgumentNullException(nameof(options));
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachFromHeader<TContext>>()
.SetOrder(AttachUserAgentHeader<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
.Build();
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var request = context.Transaction.GetHttpRequestMessage() ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0173));
// Attach the contact address specified in the options, if available.
request.Headers.From = _options.CurrentValue.ContactAddress?.ToString();
return default;
}
}
/// <summary>
/// Contains the logic responsible for attaching the query string parameters to the HTTP request.
/// </summary>

9
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpOptions.cs

@ -6,6 +6,7 @@
using System.Net;
using System.Net.Http.Headers;
using System.Net.Mail;
using Polly;
using Polly.Extensions.Http;
@ -25,7 +26,13 @@ public sealed class OpenIddictClientSystemNetHttpOptions
.WaitAndRetryAsync(4, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));
/// <summary>
/// Gets or sets the product information used in the user agent header that is
/// Gets or sets the contact mail address used in the "From" header that is
/// attached to the backchannel HTTP requests sent to the authorization server.
/// </summary>
public MailAddress? ContactAddress { get; set; }
/// <summary>
/// Gets or sets the product information used in the "User-Agent" header that is
/// attached to the backchannel HTTP requests sent to the authorization server.
/// </summary>
public ProductInfoHeaderValue? ProductInformation { get; set; }

39
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpBuilder.cs

@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Net.Http.Headers;
using System.Net.Mail;
using System.Reflection;
using OpenIddict.Validation.SystemNetHttp;
using Polly;
@ -48,6 +49,38 @@ public sealed class OpenIddictValidationSystemNetHttpBuilder
return this;
}
/// <summary>
/// Sets the contact address used in the "From" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="address">The mail address.</param>
/// <returns>The <see cref="OpenIddictValidationSystemNetHttpBuilder"/> instance.</returns>
public OpenIddictValidationSystemNetHttpBuilder SetContactAddress(MailAddress address)
{
if (address is null)
{
throw new ArgumentNullException(nameof(address));
}
return Configure(options => options.ContactAddress = address);
}
/// <summary>
/// Sets the contact address used in the "From" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="address">The mail address.</param>
/// <returns>The <see cref="OpenIddictValidationSystemNetHttpBuilder"/> instance.</returns>
public OpenIddictValidationSystemNetHttpBuilder SetContactAddress(string address)
{
if (string.IsNullOrEmpty(address))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0366), nameof(address));
}
return SetContactAddress(new MailAddress(address));
}
/// <summary>
/// Replaces the default HTTP error policy used by the OpenIddict client services.
/// </summary>
@ -64,7 +97,7 @@ public sealed class OpenIddictValidationSystemNetHttpBuilder
}
/// <summary>
/// Sets the product information used in the user agent header that is attached
/// Sets the product information used in the "User-Agent" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="information">The product information.</param>
@ -80,7 +113,7 @@ public sealed class OpenIddictValidationSystemNetHttpBuilder
}
/// <summary>
/// Sets the product information used in the user agent header that is attached
/// Sets the product information used in the "User-Agent" header that is attached
/// to the backchannel HTTP requests sent to the authorization server.
/// </summary>
/// <param name="name">The product name.</param>
@ -97,7 +130,7 @@ public sealed class OpenIddictValidationSystemNetHttpBuilder
}
/// <summary>
/// Sets the product information used in the user agent header that is attached
/// Sets the product information used in the "User-Agent" header that is attached
/// to the backchannel HTTP requests sent to the authorization server based
/// on the identity of the specified .NET assembly (name and version).
/// </summary>

2
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Discovery.cs

@ -19,6 +19,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
PrepareGetHttpRequest<PrepareConfigurationRequestContext>.Descriptor,
AttachJsonAcceptHeaders<PrepareConfigurationRequestContext>.Descriptor,
AttachUserAgentHeader<PrepareConfigurationRequestContext>.Descriptor,
AttachFromHeader<PrepareConfigurationRequestContext>.Descriptor,
AttachQueryStringParameters<PrepareConfigurationRequestContext>.Descriptor,
SendHttpRequest<ApplyConfigurationRequestContext>.Descriptor,
DisposeHttpRequest<ApplyConfigurationRequestContext>.Descriptor,
@ -38,6 +39,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
PrepareGetHttpRequest<PrepareCryptographyRequestContext>.Descriptor,
AttachJsonAcceptHeaders<PrepareCryptographyRequestContext>.Descriptor,
AttachUserAgentHeader<PrepareCryptographyRequestContext>.Descriptor,
AttachFromHeader<PrepareCryptographyRequestContext>.Descriptor,
AttachQueryStringParameters<PrepareCryptographyRequestContext>.Descriptor,
SendHttpRequest<ApplyCryptographyRequestContext>.Descriptor,
DisposeHttpRequest<ApplyCryptographyRequestContext>.Descriptor,

1
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Introspection.cs

@ -22,6 +22,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
PreparePostHttpRequest<PrepareIntrospectionRequestContext>.Descriptor,
AttachJsonAcceptHeaders<PrepareIntrospectionRequestContext>.Descriptor,
AttachUserAgentHeader<PrepareIntrospectionRequestContext>.Descriptor,
AttachFromHeader<PrepareIntrospectionRequestContext>.Descriptor,
AttachBasicAuthenticationCredentials.Descriptor,
AttachFormParameters<PrepareIntrospectionRequestContext>.Descriptor,
SendHttpRequest<ApplyIntrospectionRequestContext>.Descriptor,

42
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs

@ -9,6 +9,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.IO.Compression;
using System.Net.Http.Headers;
using System.Net.Mail;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
@ -186,6 +187,47 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
}
}
/// <summary>
/// Contains the logic responsible for attaching the contact address to the HTTP request.
/// </summary>
public sealed class AttachFromHeader<TContext> : IOpenIddictValidationHandler<TContext> where TContext : BaseExternalContext
{
private readonly IOptionsMonitor<OpenIddictValidationSystemNetHttpOptions> _options;
public AttachFromHeader(IOptionsMonitor<OpenIddictValidationSystemNetHttpOptions> options)
=> _options = options ?? throw new ArgumentNullException(nameof(options));
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachFromHeader<TContext>>()
.SetOrder(AttachUserAgentHeader<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var request = context.Transaction.GetHttpRequestMessage() ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0173));
// Attach the contact address specified in the options, if available.
request.Headers.From = _options.CurrentValue.ContactAddress?.ToString();
return default;
}
}
/// <summary>
/// Contains the logic responsible for attaching the query string parameters to the HTTP request.
/// </summary>

9
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpOptions.cs

@ -6,6 +6,7 @@
using System.Net;
using System.Net.Http.Headers;
using System.Net.Mail;
using Polly;
using Polly.Extensions.Http;
@ -25,7 +26,13 @@ public sealed class OpenIddictValidationSystemNetHttpOptions
.WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));
/// <summary>
/// Gets or sets the product information used in the user agent header that is
/// Gets or sets the contact mail address used in the "From" header that is
/// attached to the backchannel HTTP requests sent to the authorization server.
/// </summary>
public MailAddress? ContactAddress { get; set; }
/// <summary>
/// Gets or sets the product information used in the "User-Agent" header that is
/// attached to the backchannel HTTP requests sent to the authorization server.
/// </summary>
public ProductInfoHeaderValue? ProductInformation { get; set; }

Loading…
Cancel
Save