用证书编程实现WCF

本文关键字:WCF 实现 编程 证书 | 更新日期: 2023-09-27 18:05:08

我对WCF很陌生,想要了解安全性。我仍然在阅读和学习,但我到了一个点,我得到了一个工作版本的WCF与证书认证。我知道代码有一些弱点;但是,我最初的目标是使用证书身份验证创建通信。此外,我希望以编程方式创建所有内容(没有Web)。配置服务或客户端的配置)。这样做的原因是客户端应该能够链接程序集(类库)并访问服务器。此外,我正在从文件系统加载证书(同样,我知道这是不安全的)。我想得到一点反馈。

下面的客户端代码片段创建了一个对象,我可以用它连接到服务器。匿名类型T是我的服务接口,例如IService。

下面是我的客户端实现:

var url = "URL TO WS";
var binding = new WSHttpBinding
{
    Security =
    {
        Mode = SecurityMode.Message,
        Message = {ClientCredentialType = MessageCredentialType.Certificate}
    }
};
var endpoint = new EndpointAddress(url);
var channelFactory = new ChannelFactory<T>(binding, endpoint);
if (channelFactory.Credentials != null)
{
    channelFactory.Credentials.ClientCertificate.Certificate =
        new X509Certificate2(@"PATH'TO'Client.pfx"); // Client Certificate PRIVATE & PUBLIC Key
    channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; // I know this is not good, but I dont have a valid certificate from a trusted entity
}
wcfClient = channelFactory.CreateChannel();
return wcfClient;

服务有点复杂。我使用。svc文件及其代码隐藏。如果我正确地理解了。svc文件的用法,那么我相信这是。net框架创建ServiceHost并自动打开它的入口点。在我的实现中,我没有打开ServiceHost,我只实现了ServiceHostFactoryBase并在.svc标记语言中引用它。看看Factory部分——这是我实现自定义主机工厂的部分。

<%@ ServiceHost Language="C#" Debug="true"
    Service="Service.Services.LevelService" CodeBehind="LevelService.svc.cs" 
    Factory="Service.Security.ServiceHostFactory.HostFactory" %>

我的自定义主机工厂看起来像这样:

public class HostFactory : ServiceHostFactoryBase
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        var serviceType = Type.GetType(constructorString);
        if (serviceType.GetInterfaces().Count() != 1)
            throw new NotImplementedException("The service can only have one implemented interface");
        var interfaceType = serviceType.GetInterfaces()[0];
        var myServiceHost = new ServiceHost(serviceType, baseAddresses);
        var httpBinding = new WSHttpBinding();
        httpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
        httpBinding.Security.Mode = SecurityMode.Message;
        myServiceHost.Credentials.ServiceCertificate.Certificate = new X509Certificate2(@"PATH'TO'Server.pfx");
        myServiceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
        myServiceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new MyX509CertificateValidator();
        myServiceHost.Credentials.ClientCertificate.Certificate = new X509Certificate2(@"PATH'TO'Client.cer");
        myServiceHost.AddServiceEndpoint(interfaceType, httpBinding, String.Empty);
        return myServiceHost;
    }
}

自定义验证器还没有做很多事情,但这里也有:

public class MyX509CertificateValidator : X509CertificateValidator
{
    public override void Validate(X509Certificate2 certificate)
    {
        // Check that there is a certificate.
        if (certificate == null)
        {
            throw new ArgumentNullException("certificate");
        }
        // Check that the certificate issuer matches the configured issuer.
        //throw new SecurityTokenValidationException("Certificate was not issued by a trusted issuer");
    }
}

如果我理解正确的话,服务器只注册了客户端的公钥,因为我只引用了。cer文件。

我现在的大问题是,如果我想在生产服务器上得到这样的东西——让我们假设没有人会真正得到可执行文件(包括证书),这是一个可能的解决方案,让不受欢迎的人离开我的web服务吗?基本上,我不希望任何人使用我的web服务——除非您拥有适当的证书。另外,我在客户端设置的部分有多大的问题:

CertificateValidationMode = X509CertificateValidationMode.None

我知道有很多问题-但总的来说,我想知道我是否在这个实现中犯了一些基本错误。

用证书编程实现WCF

Ok,

在看了很多教程和演示应用程序之后,我发现最好的方法是在Windows上使用证书存储。但是,我仍然可能会考虑一种混合解决方案,其中服务器将证书存储在证书存储中,而客户机将其嵌入到资源中。如果您正在与WCF和证书作斗争,请查看这些链接:

IIS7权限概述- ApplicationPoolIdentity

我能够创建传输和消息安全的WCF web服务。我建议阅读链接的文章,因为有很多信息可以帮助您理解证书及其用法。特别是在处理自签名证书时!

我最终实现wsHttpBinding使用消息安全模式+客户端证书与ChainTrust。

希望这将帮助别人!