我对WCF很新,并试图了解安全问题。我还在阅读和学习,但是我找到了一个带有证书认证的WCF工作版本。我知道代码有一些缺点;但是,我最初的目标是使用证书身份验证创建通信。此外,我想以编程方式创建所有内容(没有服务或客户端的Web.config配置)。这样做的原因是客户端应该能够链接程序集(类库)并访问服务器。此外,我正在从文件系统加载证书(再次,我知道这是不安全的)。我想得到一些反馈。
以下客户端代码段正在创建一个可用于连接服务器的对象。匿名类型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");
}
}
如果我理解正确,服务器只有注册客户端的PUBLIC密钥,因为我只引用.cer文件。
现在我的一个大问题是,如果我想在生产服务器上得到这样的东西 - 并且假设没有人会真正获得可执行文件(包括证书),这是否是一个可能的解决方案,可以阻止不受欢迎的人我的网络服务?基本上,我不希望任何人使用我的网络服务 - 只有你有合适的证书。另外,我在客户端上设置的部分有多少问题:
CertificateValidationMode = X509CertificateValidationMode.None
我知道有很多问题 - 但总的来说,我想知道我是否在这个实施中犯了一些基本错误。
答案 0 :(得分:0)
确定,
经过大量的教程和演示应用程序后,我发现最好的方法是在Windows上使用证书存储。但是,我仍然可以考虑一种混合解决方案,其中服务器在证书存储中具有证书,并且客户端将其嵌入资源中。如果您正在努力使用WCF和证书,请查看这些链接:
IIS7 Permissions Overview - ApplicationPoolIdentity
我能够创建Transport以及Message安全的WCF Web服务。我建议阅读链接的文章,因为有太多的信息会让你了解证书及其用法。特别是在处理自签证书时!
我最终使用MessageTrust使用Message Security Mode + Client Certificate实现了wsHttpBinding。
希望这会帮助别人!