BasicAuthentication update - added guest support

messaging
Tudor Stanciu 2021-06-26 21:20:49 +03:00
parent 18e202752a
commit 5f40130ada
6 changed files with 69 additions and 6 deletions

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Http;
using System;
namespace NDB.Security.Authentication.Identity.Abstractions
{
public interface IAuthenticationOptions
{
Func<HttpRequest, bool> AuthenticateAsGuest { get; }
int GuestUserId { get; }
string GuestUserName { get; }
}
}

View File

@ -1,6 +1,7 @@
using IdentityServer.Wrapper; using IdentityServer.Wrapper;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using NDB.Security.Authentication.Identity.Abstractions;
using System; using System;
namespace NDB.Security.Authentication.Identity namespace NDB.Security.Authentication.Identity
@ -9,11 +10,17 @@ namespace NDB.Security.Authentication.Identity
{ {
public static IServiceCollection AddBasicAuthentication(this IServiceCollection services, string identityServerBaseAddress) public static IServiceCollection AddBasicAuthentication(this IServiceCollection services, string identityServerBaseAddress)
{ {
if (string.IsNullOrEmpty(identityServerBaseAddress)) services.AddBasicAuthentication(identityServerBaseAddress, new Services.AuthenticationOptions());
throw new Exception($"Identity server base address must be provided."); return services;
}
public static IServiceCollection AddBasicAuthentication(this IServiceCollection services, string identityServerBaseAddress, IAuthenticationOptions authenticationOptions)
{
Validate(identityServerBaseAddress, authenticationOptions);
// Identity server // Identity server
services.UseIdentityServices(identityServerBaseAddress); services.UseIdentityServices(identityServerBaseAddress);
services.AddSingleton(authenticationOptions);
// configure basic authentication // configure basic authentication
services.AddAuthentication("BasicAuthentication") services.AddAuthentication("BasicAuthentication")
@ -21,5 +28,15 @@ namespace NDB.Security.Authentication.Identity
return services; return services;
} }
private static void Validate(string identityServerBaseAddress, IAuthenticationOptions authenticationOptions)
{
if (string.IsNullOrEmpty(identityServerBaseAddress))
throw new ArgumentException("Identity server base address must be provided.");
var guestFuncDefined = authenticationOptions.AuthenticateAsGuest != null;
if (guestFuncDefined && string.IsNullOrEmpty(authenticationOptions.GuestUserName))
throw new ArgumentException("Guest function is defined, but guest user name is not set.");
}
} }
} }

View File

@ -3,6 +3,7 @@ using IdentityServer.Wrapper.Services;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NDB.Security.Authentication.Identity.Abstractions;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Security.Claims; using System.Security.Claims;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
@ -13,17 +14,28 @@ namespace NDB.Security.Authentication.Identity
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{ {
private readonly IIdentityService _identityService; private readonly IIdentityService _identityService;
private readonly IAuthenticationOptions _authenticationOptions;
public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IIdentityService identityService) public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IIdentityService identityService, IAuthenticationOptions authenticationOptions)
: base(options, logger, encoder, clock) : base(options, logger, encoder, clock)
{ {
_identityService = identityService; _identityService = identityService;
_authenticationOptions = authenticationOptions;
} }
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{ {
if (!Request.Headers.ContainsKey("Authorization")) if (!Request.Headers.ContainsKey("Authorization"))
{
var authenticateAsGuest = _authenticationOptions.AuthenticateAsGuest?.Invoke(Request) ?? false;
if (authenticateAsGuest)
{
var guestTicket = GetAuthenticationTicket(new User() { UserId = _authenticationOptions.GuestUserId, UserName = _authenticationOptions.GuestUserName });
return AuthenticateResult.Success(guestTicket);
}
return AuthenticateResult.Fail("Missing Authorization Header"); return AuthenticateResult.Fail("Missing Authorization Header");
}
User user; User user;
try try
@ -40,6 +52,12 @@ namespace NDB.Security.Authentication.Identity
if (user == null) if (user == null)
return AuthenticateResult.Fail("Invalid Username or Password"); return AuthenticateResult.Fail("Invalid Username or Password");
var ticket = GetAuthenticationTicket(user);
return AuthenticateResult.Success(ticket);
}
private AuthenticationTicket GetAuthenticationTicket(User user)
{
var claims = new[] { var claims = new[] {
new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()), new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()),
new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.Name, user.UserName),
@ -49,7 +67,7 @@ namespace NDB.Security.Authentication.Identity
var principal = new ClaimsPrincipal(identity); var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, Scheme.Name); var ticket = new AuthenticationTicket(principal, Scheme.Name);
return AuthenticateResult.Success(ticket); return ticket;
} }
} }
} }

View File

@ -7,6 +7,7 @@
<RepositoryUrl>https://dev.azure.com/tstanciu94/NDB</RepositoryUrl> <RepositoryUrl>https://dev.azure.com/tstanciu94/NDB</RepositoryUrl>
<RepositoryType>Git</RepositoryType> <RepositoryType>Git</RepositoryType>
<PackageTags>NDB BasicAuthentication Identity</PackageTags> <PackageTags>NDB BasicAuthentication Identity</PackageTags>
<Version>1.0.1</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Http;
using NDB.Security.Authentication.Identity.Abstractions;
using System;
namespace NDB.Security.Authentication.Identity.Services
{
public class AuthenticationOptions : IAuthenticationOptions
{
public Func<HttpRequest, bool> AuthenticateAsGuest { get; set; }
public int GuestUserId { get; set; }
public string GuestUserName { get; set; }
}
}

View File

@ -18,11 +18,11 @@ Push packages:
dotnet nuget push NDB.Application.DataContracts.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget dotnet nuget push NDB.Application.DataContracts.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget
dotnet nuget push NDB.Extensions.Swagger.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget dotnet nuget push NDB.Extensions.Swagger.1.0.1.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget
dotnet nuget push NDB.Extensions.Http.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget dotnet nuget push NDB.Extensions.Http.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget
dotnet nuget push NDB.Security.Authentication.Identity.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget dotnet nuget push NDB.Security.Authentication.Identity.1.0.1.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget
dotnet nuget push NDB.Extensions.Caching.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget dotnet nuget push NDB.Extensions.Caching.1.0.0.nupkg -k ***REMOVED*** -s http://stawebsrv:8081/NuGetServer/nuget
####################################################################################################################################################### #######################################################################################################################################################