Skip to content

Commit

Permalink
fix: rename header authentication name that not easy misunderstanding
Browse files Browse the repository at this point in the history
  • Loading branch information
jxnkwlp committed Sep 23, 2023
1 parent 97ee026 commit 5c150f3
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 120 deletions.
2 changes: 1 addition & 1 deletion samples/SampleWeb/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
options.ForwardDefaultSelector = (s) =>
{
var authorization = (string?)s.Request.Headers.Authorization;
if (authorization?.StartsWith(ApiKeyDefaults.AuthenticationSchemeName) == true)
if (authorization?.StartsWith(ApiKeyDefaults.HeaderAuthenticationSchemeName) == true)
return ApiKeyDefaults.AuthenticationScheme;

return IdentityConstants.ApplicationScheme;
Expand Down
8 changes: 4 additions & 4 deletions src/Authentication.ApiKey/source/ApiKeyDefaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ public static class ApiKeyDefaults
public const string AuthenticationScheme = "ApiKey";

/// <summary>
///
/// Default value for header name
/// </summary>
public const string HeaderName = "X-ApiKey";

/// <summary>
///
/// Default value for query name
/// </summary>
public const string QueryStringName = "x-apikey";

/// <summary>
///
/// Default value for header authentication name
/// </summary>
public const string AuthenticationSchemeName = "ApiKey";
public const string HeaderAuthenticationSchemeName = "ApiKey";
}
10 changes: 5 additions & 5 deletions src/Authentication.ApiKey/source/ApiKeyEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ namespace Passingwind.AspNetCore.Authentication.ApiKey;
public class ApiKeyEvents
{
/// <summary>
///
/// Invoked when a protocol message is first received.
/// </summary>
public Func<ApiKeyMessageReceivedContext, Task> OnMessageReceived { get; set; } = context => Task.CompletedTask;
/// <summary>
///
/// Invoked after the security token has passed validation and a ClaimsIdentity has been generated.
/// </summary>
public Func<ApiKeyTokenValidatedContext, Task> OnTokenValidated { get; set; } = context => Task.CompletedTask;
/// <summary>
///
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
/// </summary>
public Func<ApiKeyAuthenticationFailedContext, Task> OnAuthenticationFailed { get; set; } = context => Task.CompletedTask;
/// <summary>
///
/// Invoked before a challenge is sent back to the caller.
/// </summary>
public Func<ApiKeyChallengeContext, Task> OnChallenge { get; set; } = context => Task.CompletedTask;
/// <summary>
///
/// Invoked if Authorization fails and results in a Forbidden response
/// </summary>
public Func<ApiKeyForbiddenContext, Task> OnForbidden { get; set; } = context => Task.CompletedTask;

Expand Down
47 changes: 25 additions & 22 deletions src/Authentication.ApiKey/source/ApiKeyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,52 @@
namespace Passingwind.AspNetCore.Authentication.ApiKey;

/// <summary>
///
/// Extension methods to configure ApiKey authentication.
/// </summary>
public static class ApiKeyExtensions
{
/// <summary>
///
/// Enables ApiKey authentication using the default scheme
/// </summary>
/// <typeparam name="TApiKeyProvider"></typeparam>
/// <param name="builder"></param>
/// <returns></returns>
public static AuthenticationBuilder AddApiKey<TApiKeyProvider>(this AuthenticationBuilder builder) where TApiKeyProvider : class, IApiKeyProvider
{
return AddApiKey<TApiKeyProvider>(builder: builder, scheme: ApiKeyDefaults.AuthenticationScheme, displayName: null, configureOptions: null);
return AddApiKey<TApiKeyProvider>(builder: builder, authenticationScheme: ApiKeyDefaults.AuthenticationScheme, displayName: null, configureOptions: _ => { });
}

/// <summary>
///
/// Enables ApiKey authentication
/// </summary>
/// <typeparam name="TApiKeyProvider"></typeparam>
/// <param name="builder"></param>
/// <param name="configureOptions"></param>
/// <returns></returns>
public static AuthenticationBuilder AddApiKey<TApiKeyProvider>(this AuthenticationBuilder builder, Action<ApiKeyOptions>? configureOptions = null) where TApiKeyProvider : class, IApiKeyProvider
public static AuthenticationBuilder AddApiKey<TApiKeyProvider>(this AuthenticationBuilder builder, string authenticationScheme) where TApiKeyProvider : class, IApiKeyProvider
{
return AddApiKey<TApiKeyProvider>(builder: builder, scheme: ApiKeyDefaults.AuthenticationScheme, displayName: null, configureOptions: configureOptions);
return AddApiKey<TApiKeyProvider>(builder: builder, authenticationScheme: authenticationScheme, displayName: null, configureOptions: _ => { });
}

/// <summary>
///
/// Enables ApiKey authentication
/// </summary>
/// <typeparam name="TApiKeyProvider"></typeparam>
/// <param name="builder"></param>
/// <param name="scheme"></param>
/// <param name="displayName"></param>
/// <param name="configureOptions"></param>
/// <returns></returns>
public static AuthenticationBuilder AddApiKey<TApiKeyProvider>(this AuthenticationBuilder builder, string scheme, string? displayName = null, Action<ApiKeyOptions>? configureOptions = null) where TApiKeyProvider : class, IApiKeyProvider
public static AuthenticationBuilder AddApiKey<TApiKeyProvider>(this AuthenticationBuilder builder, Action<ApiKeyOptions> configureOptions) where TApiKeyProvider : class, IApiKeyProvider
{
return AddApiKey<TApiKeyProvider>(builder: builder, authenticationScheme: ApiKeyDefaults.AuthenticationScheme, displayName: null, configureOptions: configureOptions);
}

/// <summary>
/// Enables ApiKey authentication
/// </summary>
public static AuthenticationBuilder AddApiKey<TApiKeyProvider>(this AuthenticationBuilder builder, string authenticationScheme, Action<ApiKeyOptions> configureOptions) where TApiKeyProvider : class, IApiKeyProvider
{
return AddApiKey<TApiKeyProvider>(builder: builder, authenticationScheme: authenticationScheme, displayName: null, configureOptions: configureOptions);
}

/// <summary>
/// Enables ApiKey authentication
/// </summary>
public static AuthenticationBuilder AddApiKey<TApiKeyProvider>(this AuthenticationBuilder builder, string authenticationScheme, string? displayName, Action<ApiKeyOptions> configureOptions) where TApiKeyProvider : class, IApiKeyProvider
{
builder.Services.TryAddTransient<IApiKeyProvider, TApiKeyProvider>();

builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<ApiKeyOptions>, ApiKeyPostConfigureOptions>());

builder.AddScheme<ApiKeyOptions, ApiKeyHandler>(scheme, displayName, configureOptions);
builder.AddScheme<ApiKeyOptions, ApiKeyHandler>(authenticationScheme, displayName, configureOptions);

builder.Services.AddTransient<ApiKeyHandler>();

Expand Down
44 changes: 9 additions & 35 deletions src/Authentication.ApiKey/source/ApiKeyHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,19 @@ namespace Passingwind.AspNetCore.Authentication.ApiKey;
/// </summary>
public class ApiKeyHandler : AuthenticationHandler<ApiKeyOptions>
{
/// <summary>
///
/// </summary>
/// <inheritdoc />
protected IApiKeyProvider ApiKeyProvider { get; }

/// <summary>
///
/// </summary>
/// <inheritdoc />
protected new ApiKeyEvents Events { get => (ApiKeyEvents)base.Events!; set => base.Events = value; }

/// <summary>
///
/// </summary>
/// <param name="options"></param>
/// <param name="logger"></param>
/// <param name="encoder"></param>
/// <param name="clock"></param>
/// <param name="apiKeyProvider"></param>
/// <inheritdoc />
public ApiKeyHandler(IOptionsMonitor<ApiKeyOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IApiKeyProvider apiKeyProvider) : base(options, logger, encoder, clock)
{
ApiKeyProvider = apiKeyProvider;
}

/// <summary>
///
/// </summary>
/// <returns></returns>
/// <inheritdoc />
protected override Task<object> CreateEventsAsync()
{
return Task.FromResult<object>(new ApiKeyEvents());
Expand Down Expand Up @@ -192,23 +178,15 @@ protected override async Task HandleChallengeAsync(AuthenticationProperties prop
}
}

/// <summary>
///
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
/// <inheritdoc />
protected override Task HandleForbiddenAsync(AuthenticationProperties properties)
{
var forbiddenContext = new ApiKeyForbiddenContext(Context, Scheme, Options);

return Events.ForbiddenAsync(forbiddenContext);
}

/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
/// <inheritdoc />
protected virtual string? GetToken(HttpRequest request)
{
if (!string.IsNullOrWhiteSpace(Options.QueryStringName) && request.Query.TryGetValue(Options.QueryStringName, out var queryToken))
Expand All @@ -217,21 +195,17 @@ protected override Task HandleForbiddenAsync(AuthenticationProperties properties
if (!string.IsNullOrWhiteSpace(Options.HeaderName) && request.Headers.TryGetValue(Options.HeaderName, out var headerToken))
return headerToken;

if (!string.IsNullOrWhiteSpace(Options.AuthenticationSchemeName) && request.Headers.ContainsKey(HeaderNames.Authorization) && AuthenticationHeaderValue.TryParse(request.Headers[HeaderNames.Authorization], out var headerValue))
if (!string.IsNullOrWhiteSpace(Options.HeaderAuthenticationSchemeName) && request.Headers.ContainsKey(HeaderNames.Authorization) && AuthenticationHeaderValue.TryParse(request.Headers[HeaderNames.Authorization], out var headerValue))
return headerValue.Parameter;

return string.Empty;
}

/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
/// <inheritdoc />
protected virtual bool CanHandle(HttpRequest request)
{
return (!string.IsNullOrWhiteSpace(Options.HeaderName) && request.Headers.ContainsKey(Options.HeaderName))
|| (!string.IsNullOrWhiteSpace(Options.QueryStringName) && request.Query.ContainsKey(Options.QueryStringName))
|| (!string.IsNullOrWhiteSpace(Options.AuthenticationSchemeName) && AuthenticationHeaderValue.TryParse(request.Headers[HeaderNames.Authorization], out var headerValue) && headerValue.Scheme.Equals(Options.AuthenticationSchemeName, System.StringComparison.OrdinalIgnoreCase));
|| (!string.IsNullOrWhiteSpace(Options.HeaderAuthenticationSchemeName) && AuthenticationHeaderValue.TryParse(request.Headers[HeaderNames.Authorization], out var headerValue) && headerValue.Scheme.Equals(Options.HeaderAuthenticationSchemeName, System.StringComparison.OrdinalIgnoreCase));
}
}
24 changes: 4 additions & 20 deletions src/Authentication.ApiKey/source/ApiKeyOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,12 @@ namespace Passingwind.AspNetCore.Authentication.ApiKey;
/// </summary>
public class ApiKeyOptions : AuthenticationSchemeOptions
{
/// <summary>
///
/// </summary>
public string? HeaderName { get; set; }
/// <summary>
///
/// </summary>

public string? QueryStringName { get; set; }
/// <summary>
///
/// </summary>
public string? AuthenticationSchemeName { get; set; }

/// <summary>
///
/// </summary>
public string? HeaderAuthenticationSchemeName { get; set; }

public string? Realm { get; set; }

/// <summary>
Expand All @@ -36,22 +26,16 @@ public class ApiKeyOptions : AuthenticationSchemeOptions
/// </summary>
public bool SaveToken { get; set; } = true;

/// <summary>
///
/// </summary>
public new ApiKeyEvents Events
{
get { return (ApiKeyEvents)base.Events!; }
set { base.Events = value; }
}

/// <summary>
///
/// </summary>
public ApiKeyOptions()
{
HeaderName = ApiKeyDefaults.HeaderName;
QueryStringName = ApiKeyDefaults.QueryStringName;
AuthenticationSchemeName = ApiKeyDefaults.AuthenticationSchemeName;
HeaderAuthenticationSchemeName = ApiKeyDefaults.HeaderAuthenticationSchemeName;
}
}
14 changes: 4 additions & 10 deletions src/Authentication.ApiKey/source/ApiKeyPostConfigureOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,15 @@

namespace Passingwind.AspNetCore.Authentication.ApiKey;

/// <summary>
///
/// </summary>
/// <inheritdoc />
public class ApiKeyPostConfigureOptions : IPostConfigureOptions<ApiKeyOptions>
{
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="options"></param>
/// <inheritdoc />
public void PostConfigure(string? name, ApiKeyOptions options)
{
if (string.IsNullOrWhiteSpace(options.HeaderName) && string.IsNullOrWhiteSpace(options.QueryStringName) && string.IsNullOrWhiteSpace(options.AuthenticationSchemeName))
if (string.IsNullOrWhiteSpace(options.HeaderName) && string.IsNullOrWhiteSpace(options.QueryStringName) && string.IsNullOrWhiteSpace(options.HeaderAuthenticationSchemeName))
{
throw new InvalidOperationException($"API key authentication must be set {nameof(ApiKeyOptions.HeaderName)} or {nameof(ApiKeyOptions.QueryStringName)} or {nameof(ApiKeyOptions.AuthenticationSchemeName)}");
throw new InvalidOperationException($"API key authentication must be set {nameof(ApiKeyOptions.HeaderName)} or {nameof(ApiKeyOptions.QueryStringName)} or {nameof(ApiKeyOptions.HeaderAuthenticationSchemeName)}");
}
}
}
25 changes: 6 additions & 19 deletions src/Authentication.ApiKey/source/ApiKeyValidationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,18 @@

namespace Passingwind.AspNetCore.Authentication.ApiKey;

/// <summary>
///
/// </summary>
/// <inheritdoc />
public class ApiKeyValidationResult
{
/// <summary>
///
/// </summary>
/// <inheritdoc />
public ClaimsIdentity Identity { get; protected set; } = null!;

/// <summary>
///
/// </summary>
/// <inheritdoc />
public Exception Exception { get; set; } = null!;

/// <summary>
///
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
/// <inheritdoc />
public static ApiKeyValidationResult Failed(Exception exception) => new ApiKeyValidationResult() { Exception = exception };
/// <summary>
///
/// </summary>
/// <param name="identity"></param>
/// <returns></returns>

/// <inheritdoc />
public static ApiKeyValidationResult Success(ClaimsIdentity identity) => new ApiKeyValidationResult() { Identity = identity };
}
4 changes: 2 additions & 2 deletions src/Authentication.ApiKey/source/IApiKeyProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
namespace Passingwind.AspNetCore.Authentication.ApiKey;

/// <summary>
///
/// The apikey authentication verification provider
/// </summary>
public interface IApiKeyProvider
{
/// <summary>
///
/// verification
/// </summary>
/// <param name="apiKey"></param>
/// <param name="cancellationToken"></param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
<AnalysisLevel>latest</AnalysisLevel>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<FileVersion>$(AssemblyVersion)</FileVersion>
<AssemblyVersion>0.1</AssemblyVersion>
<AssemblyVersion>0.2</AssemblyVersion>
<NoWarn>1701;1702;CS1591</NoWarn>
</PropertyGroup>

<PropertyGroup>
Expand All @@ -23,7 +24,7 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<IncludeSymbols>True</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageVersion>0.1.0</PackageVersion>
<PackageVersion>0.2.0</PackageVersion>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 5c150f3

Please sign in to comment.