C# 自定义声明不会在中间件之外持久存在
我正在尝试创建自定义声明并在整个会话中保持它们。不幸的是,它们似乎不能在中间件本身之外持久存在。我错过什么了吗C# 自定义声明不会在中间件之外持久存在,c#,asp.net-core,C#,Asp.net Core,我正在尝试创建自定义声明并在整个会话中保持它们。不幸的是,它们似乎不能在中间件本身之外持久存在。我错过什么了吗 using System; using System.Collections.Generic; using System.DirectoryServices.AccountManagement; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.A
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>();
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.DirectoryServices.AccountManagement;
使用System.Linq;
使用System.Security.Claims;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Builder;
使用Microsoft.AspNetCore.Http;
使用Microsoft.Extensions.Caching.Distributed;
使用SRD数据;
使用SRD.Extensions;
名称空间SRD.Security
{
公共类ServerClaimsMiddle软件
{
private readonly RequestDelegate\u next;
公共服务器ClaimsMiddleware(RequestDelegate下一步)
{
_下一个=下一个;
}
private const string claimslastcheckey=“ClaimsLastChecked”;
公共异步任务调用(HttpContext上下文、DbContext DbContext、IDistributedCache缓存)
{
if(context.User.Identity.IsAuthenticated)
{
var claimsLastChecked=await cache.RetrieveFromCache(ClaimsLastCheckedKey);
如果(!claimsLastChecked.HasValue)
{
var cs=新列表();
使用(var principalContext=newprincipalcontext(ContextType.Domain))
{
if(context.User.Identity是ClaimsIdentity标识)
{
var user=UserPrincipal.FindByIdentity(principalContext,identity.Name);
if(user!=null)cs.Add(新声明(CustomClaimType.DisplayName.ToString(),user.DisplayName));
}
}
var roles=await dbContext.roles.All();
foreach(roles.Where(r=>context.User.IsInRole(r.ADGroupName))中的var角色)
{
var roleClaims=dbContext.Claims.ByRole(role.ADGroupName);
var customClaims=roleClaims.Select(x=>newclaims(CustomClaimType.Permission.ToString(),x.Name));
cs.AddRange(客户索赔);
}
if(cs.Any())context.User.AddIdentity(newclaimsidentity(cs,“Kerbros”);
SaveToCache(ClaimsLastCheckedKey,DateTimeOffset.Now,newtimespan(0,0,15,0));
}
}
等待下一步(上下文);
}
}
公共静态类ServerClaimsMiddlewareExtensions
{
公共静态IApplicationBuilder UseServerClaimsMiddware(
此IApplicationBuilder(应用程序生成器)
{
返回builder.UseMiddleware();
}
}
}
您正在将它们添加到ClaimsPrincipal中,但这不会将数据保留在任何地方。
当ASP.NET Core对请求进行身份验证时,它会从cookie/token/其他内容创建ClaimsPrincipal。
它不会自动转到另一个方向;修改主体纯粹是在内存中进行的
如果您的应用程序是创建cookie/令牌的应用程序,
我认为在修改主体后,可以通过在中间件中调用context.SignInAsync()
来编写一个新的
// you need this import
using Microsoft.AspNetCore.Authentication;
// In your middleware Invoke()
await context.SignInAsync(context.User);
如果尚未配置默认登录方案,还可以为SignInAsync()指定身份验证方案