You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.2 KiB

using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
using Easy.DDD.Domain.Repositories;
using Identity.Api.DDD.Domain.Entites;
using IdentityModel;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
namespace Identity.Api.Realization;
public class CustomProfileService : IProfileService
{
private readonly IRepository<IdentityUser> UserRepository;
public CustomProfileService(IRepository<IdentityUser> userService)
{
UserRepository = userService;
}
async private Task<IdentityUser> VerifySubAsync(ClaimsPrincipal subject)
{
subject = subject ?? throw new ArgumentNullException(nameof(subject));
var subjectId = subject.Claims.Where(x => x.Type == "sub").FirstOrDefault().Value;
if (!Guid.TryParse(subjectId, out Guid id))
{
throw new ArgumentException("主题是用户ID,但不是Guid!");
}
var user = await UserRepository.Set
.Include(o => o.Roles)
.Include(o => o.OrganizationUnits)
.FirstOrDefaultAsync(o => o.Id == id);
if (user == null)
{
throw new ArgumentException("无效的主题标识符");
}
return user;
}
async public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
IdentityUser user = await VerifySubAsync(context.Subject);
context.IssuedClaims = GetClaimsFromUser(user);
}
async public Task IsActiveAsync(IsActiveContext context)
{
IdentityUser user = await VerifySubAsync(context.Subject);
context.IsActive =
!user.LockoutEnabled ||
!user.LockoutEnd.HasValue ||
user.LockoutEnd <= DateTime.Now;
}
private static List<Claim> GetClaimsFromUser(IdentityUser user)
{
var claims = new List<Claim>
{
new Claim("U", user.Id.ToString()),
new Claim(JwtClaimTypes.NickName, user.NickName)
};
if (user.Roles.Count != 0)
{
var claim = new Claim(JwtClaimTypes.Role, string.Join(",", user.Roles.Select(o => o.RoleId)));
claims.Add(claim);
}
return claims;
}
}