Files
Core.Thalos.BuildingBlocks/Core.Thalos.BuildingBlocks/Handlers/GoogleAccessTokenAuthenticationHandler.cs

63 lines
2.5 KiB
C#

using Google.Apis.Auth;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using System.Text.Encodings.Web;
namespace Core.Thalos.BuildingBlocks
{
public class GoogleAccessTokenAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
IConfiguration config) : AuthenticationHandler<AuthenticationSchemeOptions>(options, logger, encoder)
{
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.ContainsKey("Authorization"))
return AuthenticateResult.Fail("Missing Authorization header");
var authHeader = Request.Headers.Authorization.ToString();
if (!authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
return AuthenticateResult.Fail("Invalid Authorization header");
var idToken = authHeader["Bearer ".Length..].Trim();
GoogleJsonWebSignature.Payload payload;
try
{
payload = await GoogleJsonWebSignature.ValidateAsync(
idToken,
new GoogleJsonWebSignature.ValidationSettings
{
Audience = new[] { config["Authentication:Google:ClientId"]! }
});
}
catch (InvalidJwtException)
{
return AuthenticateResult.Fail("Invalid Google token");
}
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, payload.Subject),
new Claim(ClaimTypes.Email, payload.Email),
new Claim(ClaimTypes.Name, payload.Name ?? "")
};
var identity = new ClaimsIdentity(claims, Schemes.GoogleScheme);
var principal = new ClaimsPrincipal(identity);
var userEmail = principal.FindFirst(ClaimTypes.Email)?.Value;
if (string.IsNullOrEmpty(userEmail) ||
!userEmail.EndsWith("@agilewebs.com", StringComparison.OrdinalIgnoreCase))
return AuthenticateResult.Fail("Unauthorized Access");
var ticket = new AuthenticationTicket(principal, Schemes.GoogleScheme);
return AuthenticateResult.Success(ticket);
}
}
}