using System.Reflection;
using System.Security.Claims;
using Dpz.Core.Auth.Models;
using Dpz.Core.Infrastructure;
using Dpz.Core.Public.ViewModel;
using Microsoft.AspNetCore.Identity;
using OpenIddict.Abstractions;
namespace Dpz.Core.Auth.Service;
public class OidcUserInfoClaimsPrincipalFactory : IUserClaimsPrincipalFactory<VmUserInfo>
{
private static readonly Lazy<PropertyInfo[]> VmUserInfoProperties = new(
() =>
typeof(VmUserInfo)
.GetProperties()
.Where(x => x.Name != nameof(VmUserInfo.Email))
.ToArray()
);
public Task<ClaimsPrincipal> CreateAsync(VmUserInfo user)
{
var claims = VmUserInfoProperties
.Value.Select(x => new Claim(
x.Name,
ApplicationTools.GetGetter<VmUserInfo>(x.Name)?.Invoke(user)?.ToString() ?? ""
))
.ToList();
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id));
// sub
claims.Add(new Claim(OpenIddictConstants.Claims.Subject, user.Id));
// OIDC 标准 name → 显示名
claims.Add(new Claim(OpenIddictConstants.Claims.Name, user.Name));
claims.Add(new Claim(OpenIddictConstants.Claims.Nickname, user.Name));
claims.Add(new Claim("username", user.Id));
claims.Add(
new Claim(OpenIddictConstants.Claims.UpdatedAt, DateTime.Now.ToTimeStamp().ToString())
);
claims.Add(new Claim(OpenIddictConstants.Claims.Email, user.Email));
var principal = new ClaimsPrincipal(
new ClaimsIdentity(claims, ConstValues.DefaultScheme, "Name", "Permissions")
);
return Task.FromResult(principal);
}
}