Authentication finally moved to the dotnet way in webapi, ready to be added to to deal with users and such
Introspection access point properly uses basic auth of client id and secret to access
This commit is contained in:
64
WebAPI/Auth/CustomAuthorizationFilter.cs
Normal file
64
WebAPI/Auth/CustomAuthorizationFilter.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using WebAPI.Data;
|
||||
|
||||
namespace WebAPI.Auth
|
||||
{
|
||||
public class OIDCAuthorization : ServiceFilterAttribute
|
||||
{
|
||||
public OIDCAuthorization() : base(typeof(CustomAuthorizationFilter))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Authorization filter for checking the bearer token against the OIDC service.
|
||||
/// Will short circuit on an invalid token
|
||||
///
|
||||
/// </summary>
|
||||
public class CustomAuthorizationFilter: IAsyncAuthorizationFilter
|
||||
{
|
||||
private readonly ILogger<CustomAuthorizationFilter> _logger;
|
||||
private readonly OIDCService _oidcService;
|
||||
private readonly AppDbContext _appDbContext;
|
||||
|
||||
public CustomAuthorizationFilter(ILogger<CustomAuthorizationFilter> logger, OIDCService oidcService, AppDbContext appDbContext)
|
||||
{
|
||||
_logger = logger;
|
||||
_oidcService = oidcService;
|
||||
_appDbContext = appDbContext;
|
||||
}
|
||||
|
||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpContext = context.HttpContext;
|
||||
var bearerToken = httpContext?.Request?.Headers[HeaderNames.Authorization].FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(bearerToken))
|
||||
{
|
||||
throw new Exception("Need a token");
|
||||
}
|
||||
|
||||
string token = bearerToken.Split(" ").ElementAt(1);
|
||||
if (!await _oidcService.ValidateAccessToken(token))
|
||||
{
|
||||
throw new Exception("bad token");
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
context.Result = new ForbidResult(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
WebAPI/Auth/OIDCAuthHandler.cs
Normal file
58
WebAPI/Auth/OIDCAuthHandler.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using WebAPI.Data;
|
||||
|
||||
namespace WebAPI.Auth
|
||||
{
|
||||
public class OIDCTokenAuthenticationHandler : AuthenticationHandler<OIDCTokenAuthenticationOptions>
|
||||
{
|
||||
private readonly OIDCService _oidcService;
|
||||
public OIDCTokenAuthenticationHandler(IOptionsMonitor<OIDCTokenAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, OIDCService oidcService) : base(options, logger, encoder, clock)
|
||||
{
|
||||
_oidcService = oidcService;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
var bearerToken = Request.Headers[HeaderNames.Authorization].FirstOrDefault() ?? "";
|
||||
if (string.IsNullOrEmpty(bearerToken))
|
||||
{
|
||||
return AuthenticateResult.Fail("no token");
|
||||
}
|
||||
|
||||
var token = bearerToken.Split(" ").ElementAt(1);
|
||||
if (!await _oidcService.ValidateAccessToken(token))
|
||||
{
|
||||
return AuthenticateResult.Fail("failed to validate token");
|
||||
}
|
||||
|
||||
var identity = new ClaimsIdentity(new[]
|
||||
{
|
||||
new Claim(ClaimTypes.Authentication, token)
|
||||
}, Scheme.Name);
|
||||
var principal = new ClaimsPrincipal(identity);
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme.Name));
|
||||
}
|
||||
}
|
||||
|
||||
public class OIDCTokenAuthenticationOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
public string OIDCIntrospectionEndpoint { get; set; }
|
||||
public string OIDCClientId { get; set; }
|
||||
public string OIDCClientSecret { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class OIDCTokenAuthenticationDefaults
|
||||
{
|
||||
public static string DefaultScheme => "OIDCAuthentication";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user