Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .net core 5.0 CurrentPrincipal重置值_C#_.net Core_Current Principal - Fatal编程技术网

C# .net core 5.0 CurrentPrincipal重置值

C# .net core 5.0 CurrentPrincipal重置值,c#,.net-core,current-principal,C#,.net Core,Current Principal,我有一个.net core 5.0应用程序,它需要额外的证书验证,并根据证书在db中获得某些角色。我将这些作为声明存储在Thread.CurrentPrincipal或HttpContext.User中。但当调用到达控制器时,这两个函数都会返回其默认值 这是Startup.cs public class Startup { public Startup(IConfiguration configuration) { Configuration = configur

我有一个.net core 5.0应用程序,它需要额外的证书验证,并根据证书在db中获得某些角色。我将这些作为声明存储在Thread.CurrentPrincipal或HttpContext.User中。但当调用到达控制器时,这两个函数都会返回其默认值

这是Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    ....

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
        .AddCertificate(options =>
        {
            options.RevocationMode = X509RevocationMode.NoCheck;
            options.AllowedCertificateTypes = CertificateTypes.All;
            options.Events = new CertificateAuthenticationEvents
            { //container.Resolve<CertificateHandler>();
                OnCertificateValidated = context =>
                {
                    if (!ValidateCertificate(context.ClientCertificate))
                    {
                        CreateErrorResponse(context, StatusCodes.Status403Forbidden, MaloConstants.NoValidClientCertificateReceived);
                        return Task.CompletedTask;
                    }

                    var certRoles = certificateProcessor.GetRoleIDs(context.ClientCertificate)
                    var roleClaims = certRoles.Roles.Distinct().OrderBy(r => r)
                        .Select(s => new Claim(ClaimsHelper.MALoInternalRole, s.ToString(CultureInfo.InvariantCulture), typeof(int).Name)).ToList();
                    var id = new ClaimsIdentity(roleClaims, AuthenticationType.X509.ToString());

                    var principal = new ClaimsPrincipal(new[] { id });

                    Thread.CurrentPrincipal = principal;
                    context.HttpContext.User = principal;
                    context.Success();
                    return Task.CompletedTask;
                }
            };
        });

        services.AddCertificateForwarding(options =>
        {
            options.CertificateHeader = "X-SSL-CERT";
            options.HeaderConverter = (headerValue) =>
            {
                X509Certificate2 clientCertificate = null;

                if (!string.IsNullOrWhiteSpace(headerValue))
                {
                    byte[] bytes = StringToByteArray(headerValue);
                    clientCertificate = new X509Certificate2(bytes);
                }

                return clientCertificate;
            };
        });

        services.AddControllers().AddNewtonsoftJson(o => o.SerializerSettings.ContractResolver = new DefaultContractResolver());
    }
    ....
    private static byte[] StringToByteArray(string hex)
    {
        int NumberChars = hex.Length;
        byte[] bytes = new byte[NumberChars / 2];

        for (int i = 0; i < NumberChars; i += 2)
        {
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
        }

        return bytes;
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        var logger = new NLogger();
        logger.Info("Application Configure started");
        
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseCertificateForwarding();
        app.UseAuthentication();

        app.UseAuthorization();
        app.UseMiddleware<ContentNegociationHandler>();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

        logger.Info("Application Configure completed");
    }
}
公共类启动
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
....
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
services.AddAuthentication(
CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(选项=>
{
options.RevocationMode=X509RevocationMode.NoCheck;
options.AllowedCertificateTypes=CertificateTypes.All;
options.Events=新的CertificateAuthenticationEvents
{//container.Resolve();
OnCertificateValidated=上下文=>
{
如果(!ValidateCertificate(context.ClientCertificate))
{
CreateErrorResponse(上下文、StatusCodes.Status403禁止、MalocConstants.NoValidClientCertificateReceived);
返回Task.CompletedTask;
}
var certRoles=certificateProcessor.GetRoleIDs(context.ClientCertificate)
var roleClaims=certRoles.Roles.Distinct().OrderBy(r=>r)
.Select(s=>newclaim(ClaimsHelper.MALoInternalRole,s.ToString(CultureInfo.InvariantCulture),typeof(int.Name)).ToList();
var id=newclaimsidentity(roleClaims,AuthenticationType.X509.ToString());
var principal=newclaimsprincipal(new[]{id});
Thread.CurrentPrincipal=主体;
context.HttpContext.User=主体;
context.Success();
返回Task.CompletedTask;
}
};
});
services.AddCertificateForwarding(选项=>
{
options.CertificateHeader=“X-SSL-CERT”;
options.HeaderConverter=(headerValue)=>
{
X509Certificate2 clientCertificate=null;
如果(!string.IsNullOrWhiteSpace(headerValue))
{
字节[]字节=StringToByteArray(headerValue);
clientCertificate=新的X509Certificate2(字节);
}
返回客户证书;
};
});
services.AddControllers().AddNewtonsoftJson(o=>o.SerializerSettings.ContractResolver=new DefaultContractResolver());
}
....
私有静态字节[]StringToByteArray(字符串十六进制)
{
int numbercars=十六进制长度;
字节[]字节=新字节[numbercars/2];
对于(int i=0;i
{
endpoints.MapControllers();
});
logger.Info(“应用程序配置完成”);
}
}
这是Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.ClearProviders();
                logging.SetMinimumLevel(LogLevel.Trace);
            })
            .UseNLog()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.ConfigureKestrel(options =>
                {
                    options.ConfigureHttpsDefaults(o =>
                        o.ClientCertificateMode =
                            ClientCertificateMode.RequireCertificate);
                });
            });
}
公共类程序
{
公共静态void Main(字符串[]args)
{
CreateHostBuilder(args.Build().Run();
}
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext,logging)=>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog()
.ConfigureWebHostDefaults(webBuilder=>
{
webBuilder.UseStartup();
webBuilder.ConfigureKestrel(选项=>
{
选项。配置HttpSDEFULTS(o=>
o、 客户认证模块=
客户认证模式。要求重新认证);
});
});
}
是否有理由不存储索赔?有解决办法吗

编辑:设置
线程的图像。CurrentPrincipal
. 控制器中
线程.CurrentPrincipal
值的图像 找到了答案: 您可以按如下方式设置新标识:

context.Principal = principal;
然后我可以使用以下命令在controller中检索新主体:

ControllerContext.HttpContext.User;

你在哪里回写数据库?@jdweng我没有。我只从数据库中读取数据。我获取当前证书的角色,并希望将这些角色作为声明存储在CurrentPrincipal中。您正在写入Thread.CurrentPrincipal,它不是CurrentPrincipal。我将CurrentPrincipal作为一般术语写入,因为我尝试同时使用Thread.CurrentPrincipal和来存储它,但当调用到达控制器时,它们都被重置。控制器解析接收响应。在控制器中解析响应后,必须更改值。