使用 .NET 8 的 IIS 未通过或接受客户端证书,相同的代码可在 .NET 4.8 中运行

问题描述 投票:0回答:1

以下 wcf 调用适用于 .NET Framework 4.8 控制台应用程序,但不适用于 .NET8 控制台应用程序。

该服务由 IIS 10 托管。在 ssl 设置中,我们将客户端证书设置为“必需”。我正在使用

Systen.ServiceModel.Http
4.10.3 包,但也在我的 .NET8 控制台项目中尝试了最新的 8.0.0 包。我也尝试以 .NET6 为目标。

IIS 日志显示:

403 7 5 15
;所以我的假设是,证书根本没有通过。

public static void Call()
{
    var channelFactory = new ChannelFactory<IExtendedParameterProvisioningPort>(new BasicHttpBinding
    {
        MaxBufferSize = 2147483647,
        MaxBufferPoolSize = 2147483647,
        MaxReceivedMessageSize = 2147483647,
        SendTimeout = new TimeSpan(0, 2, 0),
        ReceiveTimeout = new TimeSpan(0, 1, 0),
        OpenTimeout = new TimeSpan(0, 1, 0),
        CloseTimeout = new TimeSpan(0, 1, 0),
        Security = new BasicHttpSecurity()
        {
            Mode = BasicHttpSecurityMode.Transport,
            Transport = new HttpTransportSecurity()
            {
                ClientCredentialType = HttpClientCredentialType.Certificate
            }
        }
    }, new EndpointAddress("https://example.de:1460/MyWcfService.svc"));

    channelFactory.Credentials.ClientCertificate.SetCertificate(
        StoreLocation.LocalMachine,
        StoreName.My,
        X509FindType.FindByThumbprint,
        "MY-THUMBPRINT");

    channelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
        };

    var extendedParameterProvisioningPort = channelFactory.CreateChannel();

    var serviceInfoResponse = extendedParameterProvisioningPort.GetServiceInfo(new ServiceInfoRequest());
    Console.WriteLine(serviceInfoResponse.Version);
}

我收到的异常是:

The HTTP request is unauthorized with client authentication scheme 'Anonymous'.

这里有什么问题吗? .NET 6/8 还不支持客户端证书吗?

ChannelFactory
/WCF?

c# iis client-certificates wcf-security .net-8.0
1个回答
0
投票

我遇到了一个问题,WCF 中的默认 ChannelFactory 使用过时的 HttpMessageHandler,无法通过某些证书。经过一番调查,我在this帖子中发现了一个有用的建议。

为了解决这个问题,我使用新的端点行为实现了一个解决方案。这种方法归功于 petersladek。下面是实现:

首先,定义一个新的端点行为(由petersladek):

internal class CustomizeHttpHandlerEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        bindingParameters.Add(new Func<HttpClientHandler, HttpMessageHandler>(handler =>
        {
            var newHandler = new SocketsHttpHandler();
            // copy all properties set by WCF on it's handler (so we keep all configuration from wcf), see source
            // https://github.com/dotnet/wcf/blob/main/src/System.ServiceModel.Http/src/System/ServiceModel/Channels/HttpChannelFactory.cs#L272
            newHandler.AutomaticDecompression = handler.AutomaticDecompression;
            newHandler.Proxy = handler.Proxy;
            newHandler.UseProxy = handler.UseProxy;
            newHandler.UseCookies = handler.UseCookies;
            newHandler.CookieContainer = handler.CookieContainer;
            newHandler.PreAuthenticate = handler.PreAuthenticate;
            newHandler.Credentials = handler.Credentials;
            newHandler.SslOptions.EnabledSslProtocols = handler.SslProtocols;
            newHandler.SslOptions.ClientCertificates = handler.ClientCertificates;

            return newHandler;
        }));
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

    public void Validate(ServiceEndpoint endpoint) { }
}

最后,要集成此行为,您需要将其注册到 ChannelFactory:

channelFactory.Endpoint.EndpointBehaviors.Add(new CustomizeHttpHandlerEndpointBehavior());
© www.soinside.com 2019 - 2024. All rights reserved.