如何使用.net核心应用程序中的中间件来操纵当前令牌的ClaimsIdentity?

问题描述

我有一个中间件可用于如下所示的开发模式。

public class DevelopmentUserMiddleware
{
    private readonly RequestDelegate _next;

    public DevelopmentUserMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        context.Request.HttpContext.User = new ClaimsPrincipal(
            new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.NameIdentifier,"75cc7127-a31c-418b-b580-27379136b148"),new Claim(ClaimTypes.Name,"Name Surname")
            }));
        
        await _next(context);
    }
}

因此,我可以在开发平台上使用名称或id值。并使用扩展方法var usriId = User.GetUserId();获取值。

public static class ClaimsPrincipalExtensions
{
    public static Guid GetUserId(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));
      
        return Guid.Parse(principal.FindFirstValue(ClaimTypes.NameIdentifier));
    }

    public static string GetName(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        return principal.FindFirstValue(ClaimTypes.Name);
    }
}

但是现在,我在使用api资源时正在使用Bearer访问令牌。如果访问令牌中的用户名称为“ 123456”,则User.GetUserId()方法将返回“ 123456”。我的中间件不起作用。

那么我可以在开发模式下仅更改访问令牌的名称名称标识符吗?

解决方法

根据您的描述,我建议您可以阅读锥体文本中的声明并进行修改,而不用重新创建新的声明标识。

更多详细信息,您可以使用以下代码。

public class DevelopmentUserMiddleware
{
    private readonly RequestDelegate _next;

    public DevelopmentUserMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        string token = context.Request.Headers["Authorization"];
        if (!string.IsNullOrEmpty(token))
        {
            List<Claim> claims = context.User.Claims.ToList();
            claims.Remove(claims.First(x => x.Type == ClaimTypes.NameIdentifier));
            claims.Add(new Claim(ClaimTypes.NameIdentifier,"75cc7127-a31c-418b-b580-27379136b148"));
            claims.Remove(claims.First(x => x.Type == ClaimTypes.Name));
            claims.Add(new Claim(ClaimTypes.Name,"Name Surname"));
            var userIdentity = new ClaimsIdentity(claims,ClaimTypes.Name);
            context.User = new ClaimsPrincipal(userIdentity);
        }
        await _next(context);
    }
}

结果:

enter image description here