如何在 .net 核心应用程序中使用中间件操作当前令牌的 ClaimsIdentity?
How to manipulate the ClaimsIdentity of current token using middleware in .net core app?
我有一个中间件可以在开发模式下使用,如下所示。
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);
}
}
这样我就可以在开发平台上使用name或者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()
方法 returns “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);
}
}
结果:
我有一个中间件可以在开发模式下使用,如下所示。
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);
}
}
这样我就可以在开发平台上使用name或者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()
方法 returns “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);
}
}
结果: