问题描述
我试图在Kestrel Server上设置Authenticated Origin Pulls,并阻止通过IP地址直接访问其余API,但仍然允许通过Direct IP访问.
I have tried to setup Authenticated Origin Pulls on Kestrel Server and block direct access to the rest API via IP address but still allows access via Direct IP.
appsetting.json
appsetting.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Kestrel": {
"HttpsDefaults": {
"ClientCertificateMode": "RequireCertificate"
},
"Endpoints": {
"Https": {
"Url": "https://*:443",
"Certificate": {
"Path": "/home/ubuntu/domain.name.pfx",
"Password": "12345",
"AllowInvalid": false
}
}
}
}
}
MyCertificateValidationService.cs
MyCertificateValidationService.cs
using System.IO;
using System.Security.Cryptography.X509Certificates;
public class MyCertificateValidationService
{
public bool ValidateCertificate(X509Certificate2 clientCertificate)
{
var cert = new X509Certificate2("/home/ubuntu/cloudflare.pfx", "12345");
return clientCertificate.Thumbprint == cert.Thumbprint;
}
}
Program.cs
Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace ClientCertificateCheck
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args).ConfigureServices((context, services) =>
{
services.Configure<KestrelServerOptions>(
context.Configuration.GetSection("Kestrel"));
})
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}
}
Startup.cs
Startup.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace ClientCertificateCheck
{
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.AddControllers();
services.AddAuthentication(
CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
var validationService = context.HttpContext.RequestServices
.GetService<MyCertificateValidationService>();
if (validationService.ValidateCertificate(context.ClientCertificate))
{
context.Success();
}
else
{
context.Fail("invalid cert");
}
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
context.Fail("invalid cert");
return Task.CompletedTask;
}
};
});
services.Configure<KestrelServerOptions>(
Configuration.GetSection("Kestrel"));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCertificateForwarding();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
}
}
即使在完成上述设置后,当我通过域访问它时,一切正常,但是当我从IP地址访问它时,实际上应该被阻止,并且我应该收到 invalid cert
Message.无法确定我在哪里出了错.
even after above setup when I access it via domain it goes all good but when I access it from IP address access should be actually blocked and I should be receiving invalid cert
Message. Not able to identify where I am going wrong in this.
我不愿意使用任何反向代理(例如nginx或apache2),我只想使用Kestrel来实现此目的.
Edited:I am not willing to use any reverse proxy like nginx or apache2 I want to achieve this using Kestrel only.
推荐答案
不确定用于5.0的内核版本
Not sure what version of core your are using but for 5.0
Kestrel支持在配置中定义的SNI.可以使用包含主机名和HTTPS选项之间的映射的Sni对象来配置终结点.连接主机名与选项匹配,并且用于该连接.
Kestrel supports SNI defined in configuration. An endpoint can be configured with an Sni object that contains a mapping between host names and HTTPS options. The connection host name is matched to the options and they are used for that connection.
以下配置添加了一个名为MySniEndpoint的终结点,该终结点使用SNI根据主机名选择HTTPS选项
The following configuration adds an endpoint named MySniEndpoint that uses SNI to select HTTPS options based on the host name
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
这篇关于经过Cloudflare身份验证的起源与Kestrel Web Server(Linux)兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!