Kavita/API/Helpers/RolesClaimsTransformation.cs
2025-05-24 13:57:06 +02:00

47 lines
1.5 KiB
C#

using System.Collections.Generic;
using System.Security.Claims;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Kavita.Common;
using Microsoft.AspNetCore.Authentication;
namespace API.Helpers;
/// <summary>
/// Adds assigned roles from Keycloak under the default <see cref="ClaimTypes.Role"/> claim
/// </summary>
public class RolesClaimsTransformation: IClaimsTransformation
{
private const string ResourceAccessClaim = "resource_access";
private string _clientId;
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var resourceAccess = principal.FindFirst(ResourceAccessClaim);
if (resourceAccess == null) return Task.FromResult(principal);
var resources = JsonSerializer.Deserialize<Dictionary<string, Resource>>(resourceAccess.Value);
if (resources == null) return Task.FromResult(principal);
if (string.IsNullOrEmpty(_clientId))
{
_clientId = Configuration.OidcClientId;
}
var kavitaResource = resources.GetValueOrDefault(_clientId);
if (kavitaResource == null) return Task.FromResult(principal);
foreach (var role in kavitaResource.Roles)
{
((ClaimsIdentity)principal.Identity)?.AddClaim(new Claim(ClaimTypes.Role, role));
}
return Task.FromResult(principal);
}
private sealed class Resource
{
[JsonPropertyName("roles")]
public IList<string> Roles { get; set; } = [];
}
}