本文介绍了经过Cloudflare身份验证的起源与Kestrel Web Server(Linux)兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在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>"
      }
    }
  }
}

Soure

这篇关于经过Cloudflare身份验证的起源与Kestrel Web Server(Linux)兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-19 05:37