2025-10-28 13:38:57 +07:00

53 lines
1.8 KiB
C#

using Ory.Kratos.Client.Api;
using System.Security.Claims;
using Ory.Kratos.Client.Client;
using System.Text.Encodings.Web;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authentication;
namespace khmer_eid_backend.Integrations.Ory;
public class KratosHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
private readonly FrontendApi _frontendApi;
public KratosHandler(
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
IConfiguration config)
: base(options, logger, encoder)
{
var cfg = new Configuration { BasePath = config["Ory:Kratos:PublicUrl"]! };
_frontendApi = new FrontendApi(cfg);
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
var authHeader = Request.Headers["Authorization"].ToString();
if (string.IsNullOrWhiteSpace(authHeader) || !authHeader.StartsWith("Bearer "))
return AuthenticateResult.NoResult();
var token = authHeader.Substring("Bearer ".Length).Trim();
try
{
var session = await _frontendApi.ToSessionAsync(xSessionToken: token);
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, session.Identity.Id),
new Claim("phone", session.Identity.Traits.ToString() ?? "")
}, Scheme.Name);
var principal = new ClaimsPrincipal(identity);
return AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme.Name));
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to authenticate Kratos session");
return AuthenticateResult.Fail("Invalid Kratos session token");
}
}
}