仅对特定路由或控制器要求SSL客户端证书

Pau*_* W. 10 c# asp.net-core-mvc kestrel-http-server asp.net-core

我有一个使用Kestrel作为服务器的ASP.NET MVC Core项目.它既提供用户内容(asp.net mvc),又提供代理(软件)与之通信的主机Web API控制器.我已启用HTTPS和客户端证书支持.问题是我想要为调用Web API的代理(软件)要求客户端证书,但我不想要为常规基于浏览器的用户要求/提示客户端证书.

我通过以下方式启用了HTTPS /客户端证书支持:

var host = new WebHostBuilder()
.UseKestrel(options =>
{
    HttpsConnectionFilterOptions httpsoptions = new    HttpsConnectionFilterOptions();
    httpsoptions.ServerCertificate = CertUtil.GetServerCert();
    httpsoptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    httpsoptions.CheckCertificateRevocation = false;

    options.UseHttps(httpsoptions);
})
.UseUrls("http://0.0.0.0:5000", "https://0.0.0.0:5001")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
Run Code Online (Sandbox Code Playgroud)

我在Startup.cs中设置了一个单独的中间件处理程序来处理客户端证书的自定义验证.这段代码确实成功执行,在这个意义上一切正常.

问题是全局发生这种情况,我只想将客户端证书应用于特定的控制器和/或路由; 或者我真的会采取任何粒度.

通过创建两个虚拟目录,然后将SSL设置设置为接受,另一个设置为Ignore,本质上尝试创建可以在IIS中获得的相同类型的行为.带有Accept的那个将提示浏览器提供证书,而忽略的那个则不会.

我尝试将HttpsConnectionFilterOptions设置为仅指定ServerCertificate,希望不设置任何客户端证书相关选项将允许服务器在发送时接收客户端证书,否则不会提示浏览器.这似乎不起作用,因为我的中间件客户端证书处理程序在调用此函数时从未看到客户端证书(当ClientCertificateMode设置为AllowCertificate时它会这样做.

context.Connection.GetClientCertificateAsync();
Run Code Online (Sandbox Code Playgroud)

我想简而言之,Kestrel托管甚至允许更细粒度的客户端证书映射/处理,还是只能使用IIS?IIS不是此项目的选项,我宁愿不必为客户端cert api方面创建单独的项目/进程.感谢任何帮助!

Coc*_*lla 5

我一直在努力做同样的事情,与你的要求完全相同.

我得出的结论是,这是不可能的.我的解决方法是使用2个 WebHostBuilder对象-一个用于位置并不需要客户端证书,以及一个为那些.这确实有缺点,每个人都IWebHost必须在不同的端口上监听,但从你描述的场景我猜这不是一个大问题.

我在同一个过程中执行此操作,因此此解决方案符合该要求.