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 { private readonly OIDCService _oidcService; public OIDCTokenAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, OIDCService oidcService) : base(options, logger, encoder, clock) { _oidcService = oidcService; } protected override async Task 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 userInfo = await _oidcService.GetTokenDetails(token); if (userInfo == null) { return AuthenticateResult.Fail("Failed to get info for token"); } var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Authentication, token), new Claim(ClaimTypes.Name, userInfo.Name), new Claim(OIDCClaimTypes.Username, userInfo.PreferredUsername), new Claim(OIDCClaimTypes.Subject, userInfo.Sub) }, Scheme.Name); var principal = new ClaimsPrincipal(identity); return AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme.Name)); } } public class OIDCTokenAuthenticationOptions : AuthenticationSchemeOptions { } public class OIDCTokenAuthenticationDefaults { public static string DefaultScheme => "OIDCAuthentication"; } public static class OIDCClaimTypes { public static string Username => "Username"; public static string Subject => "Subject"; } }