自定义声明不会保留在中间件之外



我正在尝试创建自定义声明并通过会话保留它们。不幸的是,看起来它们不会在中间件本身之外持续存在。我错过了什么吗?

using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using SRD.Data;
using SRD.Extensions;
namespace SRD.Security
{
public class ServerClaimsMiddleware
{
private readonly RequestDelegate _next;
public ServerClaimsMiddleware(RequestDelegate next)
{
_next = next;
}
private const string ClaimsLastCheckedKey = "ClaimsLastChecked";
public async Task Invoke(HttpContext context, DbContext dbContext, IDistributedCache cache)
{
if (context.User.Identity.IsAuthenticated)
{
var claimsLastChecked = await cache.RetrieveFromCache<DateTimeOffset?>(ClaimsLastCheckedKey);
if (!claimsLastChecked.HasValue)
{
var cs = new List<Claim>();
using (var principalContext = new PrincipalContext(ContextType.Domain))
{
if (context.User.Identity is ClaimsIdentity identity)
{
var user = UserPrincipal.FindByIdentity(principalContext, identity.Name);
if (user != null) cs.Add(new Claim(CustomClaimType.DisplayName.ToString(), user.DisplayName));
}
}
var roles = await dbContext.Roles.All();
foreach (var role in roles.Where(r => context.User.IsInRole(r.ADGroupName)))
{
var roleClaims = dbContext.Claims.ByRole(role.ADGroupName);
var customClaims = roleClaims.Select(x => new Claim(CustomClaimType.Permission.ToString(), x.Name));
cs.AddRange(customClaims);
}
if (cs.Any()) context.User.AddIdentity(new ClaimsIdentity(cs, "Kerbros"));
await cache.SaveToCache(ClaimsLastCheckedKey, DateTimeOffset.Now, new TimeSpan(0, 0, 15, 0));
}
}
await _next(context);
}
}
public static class ServerClaimsMiddlewareExtensions
{
public static IApplicationBuilder UseServerClaimsMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<ServerClaimsMiddleware>();
}
}
}

您正在将它们添加到 ClaimPrincipal,但这不会将数据保留在任何地方。 当 ASP.NET 核心对请求进行身份验证时,它会从 cookie/token/其他内容创建一个声明主体。 它不会自动反其道而行之;修改主体完全在内存中。

如果你的应用是创建 Cookie/令牌的应用, 我认为您可以在修改主体后通过在中间件中调用context.SignInAsync()来编写一个新的。

// you need this import
using Microsoft.AspNetCore.Authentication;
// In your middleware Invoke()
await context.SignInAsync(context.User);

如果尚未配置默认登录方案,还可以为 SignInAsync(( 指定身份验证方案。

最新更新