asp.net 身份验证后存储DisplayName

xytpbqjk  于 2023-06-25  发布在  .NET
关注(0)|答案(1)|浏览(129)

我正在构建一个WebAPI,我的模型中有一些元数据列,比如InsertUserUpdateUser。我正在使用Microsoft.Identity对用户进行身份验证

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(_configuration.GetSection("AzureAd"))
  .EnableTokenAcquisitionToCallDownstreamApi()
  .AddMicrosoftGraph(_configuration.GetSection("MicrosoftGraph"))
  .AddInMemoryTokenCaches();

我想在成功验证后调用Graph,并将DisplayName存储在某个地方,以便在SaveChanges中的DataContext中使用它。如何才能做到这一点?

    • DataContext. cs**
public override int SaveChanges()
{
    var entries = ChangeTracker
        .Entries()
        .Where(e => e.Entity is BaseEntity && (
                e.State == EntityState.Added
                || e.State == EntityState.Modified));

    foreach (var entityEntry in entries)
    {
        ((BaseEntity)entityEntry.Entity).UpdateTimestamp = DateTime.UtcNow;
        ((BaseEntity)entityEntry.Entity).UpdateUser = "System"; //Change to logged in user

        if (entityEntry.State == EntityState.Added)
        {
            ((BaseEntity)entityEntry.Entity).InsertTimestamp = DateTime.UtcNow;
            ((BaseEntity)entityEntry.Entity).InsertUser = "System"; //Change to logged in user
        }
    }

    return base.SaveChanges();
}

我试着遵循一些教程,并尝试将其存储到ClaimsIdentity中

    • Startup. cs**
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
    options.Events ??= new JwtBearerEvents
    {
        OnTokenValidated = async context =>
        {
            var userProfileService = context.HttpContext.RequestServices.GetRequiredService<IUserProfile>();
            var user = await userProfileService.RetrieveUserProfileAsync();

            var identity = context.Principal.Identity as ClaimsIdentity;
            if (identity != null)
            {
                identity.AddClaim(new Claim("DisplayName", user.DisplayName));
            }
        }
    };
});
services.AddScoped<IUserProfile, UserProfile>();
    • UserProfile. cs**
using Microsoft.Graph;

namespace WebAPI.Services
{
    public interface IUserProfile
    {
        Task<User> RetrieveUserProfileAsync();
    }
    public class UserProfile : IUserProfile
    {
        private readonly GraphServiceClient _graphServiceClient;

        public UserProfile(GraphServiceClient graphServiceClient)
        {
            _graphServiceClient = graphServiceClient;
        }

        public async Task<User> RetrieveUserProfileAsync()
        {
            var user = await _graphServiceClient.Me.Request().GetAsync();
            return user;
        }
    }
}

为了测试,我在进行api调用时添加了这个

var claimsIdentity = _httpContextAccessor.HttpContext?.User?.Identity as ClaimsIdentity;
var userProfileDisplayName = claimsIdentity?.FindFirst("DisplayName")?.Value;
Console.WriteLine($"User: {userProfileDisplayName}");

但它只打印User:。我做错了什么,我该如何修复它?

z9gpfhce

z9gpfhce1#

没关系,我找到问题了。在Startup.csOnTokenValidated中,我添加了这一行来覆盖令牌声明中的User上下文,现在可以工作了。

OnTokenValidated = async context =>
{
  // Prior Code

  var identity = context.Principal.Identity as ClaimsIdentity;
  context.HttpContext.User = new ClaimsPrincipal(identity) ?? context.HttpContext.User;

  // Rest of the Code
}

所以在我的DataContext.cs中,我可以像这样存储显示名称

var currentUserDisplayName = _httpContextAccessor.HttpContext?.User?.FindFirst("name")?.Value ?? "System";

相关问题