Skip to content

Commit

Permalink
add IPostConfigureOptions to support DI for IBasicAuthorizationProvider,
Browse files Browse the repository at this point in the history
  • Loading branch information
doerrD committed Mar 4, 2020
1 parent 1f5b039 commit 8bdb150
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
using System;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using softaware.Authentication.Hmac.AspNetCore;

namespace softaware.Authentication.Basic.AspNetCore
{
public static class BasicAuthenticationExtensions
{
public static AuthenticationBuilder AddBasicAuthentication(
this AuthenticationBuilder builder,
string authenticationScheme,
Action<BasicAuthenticationSchemeOptions> configureOptions)
{
return builder.AddScheme<BasicAuthenticationSchemeOptions, BasicAuthenticationHandler>(authenticationScheme, authenticationScheme, configureOptions);
}
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder)
=> builder.AddBasicAuthentication(BasicAuthenticationDefaults.AuthenticationScheme, _ => { });

public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, Action<BasicAuthenticationSchemeOptions> configureOptions)
=> builder.AddBasicAuthentication(BasicAuthenticationDefaults.AuthenticationScheme, configureOptions);

public static AuthenticationBuilder AddBasicAuthentication(this AuthenticationBuilder builder, string authenticationScheme, Action<BasicAuthenticationSchemeOptions> configureOptions)
=> builder.AddBasicAuthentication(authenticationScheme, displayName: null, configureOptions);

public static AuthenticationBuilder AddBasicAuthentication(
this AuthenticationBuilder builder,
string authenticationScheme,
string displayName,
Action<BasicAuthenticationSchemeOptions> configureOptions)
public static AuthenticationBuilder AddBasicAuthentication(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<BasicAuthenticationSchemeOptions> configureOptions)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<BasicAuthenticationSchemeOptions>, BasicAuthenticationPostConfigureOptions>());
return builder.AddScheme<BasicAuthenticationSchemeOptions, BasicAuthenticationHandler>(authenticationScheme, displayName, configureOptions);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
Expand All @@ -19,10 +20,9 @@ private class ValidationResult
{
public bool Valid { get; set; }

/// <summary>
/// Only valid if <see cref="Valid"/> is true.
/// </summary>
public string Username { get; set; }

public string Password { get; set; }
}

public BasicAuthenticationHandler(IOptionsMonitor<BasicAuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
Expand All @@ -34,7 +34,7 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (this.Options.AuthorizationProvider == null)
{
throw new ArgumentException($"{this.Options.AuthorizationProvider} is absolutely necessary.");
throw new ArgumentException($"{nameof(this.Options.AuthorizationProvider)} is absolutely necessary.");
}

if (!this.Request.Headers.TryGetValue("Authorization", out var authorization))
Expand All @@ -51,7 +51,15 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()

if (validationResult.Valid)
{
var claimsToSet = new Claim[] { new Claim(ClaimTypes.NameIdentifier, validationResult.Username) };
var claimsToSet = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, validationResult.Username)
};

if (this.Options.AddPasswordAsClaim)
{
claimsToSet.Add(new Claim("Password", validationResult.Password));
}

var principal = new ClaimsPrincipal(new ClaimsIdentity(claimsToSet, BasicAuthenticationDefaults.AuthenticationType, ClaimTypes.NameIdentifier, ClaimTypes.Role));
var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), this.Options.AuthenticationScheme);
Expand Down Expand Up @@ -80,6 +88,7 @@ private async Task<ValidationResult> ValidateAsync(HttpRequest request)

result.Valid = await this.Options.AuthorizationProvider.IsAuthorizedAsync(splittedUsernamePassword[0], splittedUsernamePassword[1]);
result.Username = splittedUsernamePassword[0];
result.Password = splittedUsernamePassword[1];
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.Extensions.Options;
using softaware.Authentication.Basic.AspNetCore.AuthorizationProvider;

namespace softaware.Authentication.Basic.AspNetCore
{
public class BasicAuthenticationPostConfigureOptions : IPostConfigureOptions<BasicAuthenticationSchemeOptions>
{
private readonly IBasicAuthorizationProvider basicAuthorizationProvider;

public BasicAuthenticationPostConfigureOptions(IBasicAuthorizationProvider basicAuthorizationProvider)
{
this.basicAuthorizationProvider = basicAuthorizationProvider;
}

public void PostConfigure(string name, BasicAuthenticationSchemeOptions options)
{
if (this.basicAuthorizationProvider != null)
{
options.AuthorizationProvider = this.basicAuthorizationProvider;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,24 @@ namespace softaware.Authentication.Basic.AspNetCore
public class BasicAuthenticationSchemeOptions : AuthenticationSchemeOptions
{
public string AuthenticationScheme { get; set; }

public IBasicAuthorizationProvider AuthorizationProvider { get; set; }

/// <summary>
/// Add password as claim after successfull authentication
/// Security risks should be weighed up.
/// </summary>
public bool AddPasswordAsClaim { get; set; }

public BasicAuthenticationSchemeOptions()
{
this.AuthenticationScheme = BasicAuthenticationDefaults.AuthenticationScheme;
}

public BasicAuthenticationSchemeOptions(IBasicAuthorizationProvider basicAuthorizationProvider)
{
this.AuthenticationScheme = BasicAuthenticationDefaults.AuthenticationScheme;
this.AuthorizationProvider = basicAuthorizationProvider;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<PackageReleaseNotes>Support netstandard2.0</PackageReleaseNotes>
<PackageReleaseNotes>Add IPostConfigureOptions to support DI for IBasicAuthorizationProvider</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
Expand Down

0 comments on commit 8bdb150

Please sign in to comment.