利用企业CA WCF SSL证书 [英] WCF SSL certificate using an enterprise CA

查看:293
本文介绍了利用企业CA WCF SSL证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关的应用程序,我需要有一个SSL证书WCF服务,



因此,我们安装了它。如果我用Web浏览器槽HTTPS互联网浏览器走了,我没有问题,没有任何警告,什么都没有,所以我想,这个证书被认为是有效的窗口。



的问题是,当我试图连接到我的WCF的服务器,我得到这个错误:




 的X.509证书CN = MYHOSTNAME,OU =汤姆,O = myDomainName,

L = MyLocation,S = SO,C = CH链建设失败。即
使用证书具有无法验证的信任链。更换
证书或改变certificateValidationMode。撤销
功能无法检查吊销,因为吊销服务器
处于脱机状态。




什么可能是错误的?我怎么能知道其中链的一部分是unvalid? ?有没有办法知道什么是缺失的部分。



下面是我的代码
服务器:

 的ServiceHost MYHOST =新的ServiceHost(typeof运算(为MyService)); 
wsHttpBinding绑定=新WsHttpBinding的
{
ReaderQuotas = {MaxStringContentLength = int.MaxValue,MaxArrayLength = int.MaxValue,MAXDEPTH = int.MaxValue,MaxBytesPerRead = int.MaxValue,MaxNameTableCharCount = int.MaxValue }
MaxReceivedMessageSize = int.MaxValue
};
时间跨度timeoutSpan = TimeSpan.FromMilliseconds(超时);
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;

binding.MaxBufferPoolSize = int.MaxValue;

//我们设置的安全类型
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

//我们设置了服务器的证书
myHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,StoreName.My,X509FindType.FindBySubjectName,ConfigurationManager.AppSettings [主机名]);
myHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
//我们添加端点(我们指明哪些方法通过接口

myHost.AddServiceEndpoint(服务[港口]露,绑定的String.Format(HTTP://本地主机:{0},口));




//一些服务不一样,如果需要验证
(servicesWithoutAuth.Contains! (服务[口]))
{
//我们设置authentifier:
myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator =新CustomUserNameValidator();
myHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;


//我们设置AuthorizationPolicy
名单,LT; IAuthorizationPolicy>政策=新名单,LT ; IAuthorizationPolicy> {新CustomAuthorizationPolicy()};
myHost.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly();
}
,否则
{
//我们设置authentifier:
myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator =新NoUserNamePasswordValidator();
}

//我们绕过证书验证(我们的证书是唯一的自签名)
// HACK只是为了desactivate的SSL检查:
ServicePointManager.ServerCertificateValidationCallback + = ValidateCertificate;



// HACK:删除时调试完毕
私人静态布尔ValidateCertificate(对象发件人,X509证书证书,X509Chain链,SslPolicyErrors sslpolicyerrors)
{
返回真;
}



我的客户端:

  //远程ADRESS的形式为的net.tcp://本地主机:8000
串remoteAddress =的String.Format({0}:// {1}:{2},Tools.GetDescription(accessInfo.ServiceHost.Protocol),accessInfo.ServiceHost.HostName,accessInfo.PortNumber);

// HACK:结合取决于协议 - >切换accessInfo.ServiceHost.Protocol

//避免与大型XML的
wsHttpBinding绑定=新WsHttpBinding的seralization /反序列化问题();
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.ReaderQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
时间跨度timeoutSpan = DateTime.Now.AddMinutes(30) - DateTime.Now;
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;


// ++
binding.MaxBufferPoolSize = int.MaxValue;

//我们设置的安全类型
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

&的ChannelFactory LT; TService>的ChannelFactory =新的ChannelFactory< TService>(绑定,remoteAddress);

channelFactory.Credentials.UserName.UserName =((UsernamePasswordAuthentication)authInfos).Username;
channelFactory.Credentials.UserName.Password =((UsernamePasswordAuthentication)authInfos)。密码;


//我们设置maxItemsInObjectGraph
的foreach(OperationDescription运在channelFactory.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors .Find< DataContractSerializerOperationBehavior>();
如果(dataContractBehavior!= NULL)
{
dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
}
}
SamlSecurityTokenAuthenticator认证=新SamlSecurityTokenAuthenticator(新名单< SecurityTokenAuthenticator>(新SecurityTokenAuthenticator [] {新RsaSecurityTokenAuthenticator(),新X509SecurityTokenAuthenticator(X509CertificateValidator.None)}),TimeSpan.FromDays( 5));

_service = channelFactory.CreateChannel();


解决方案

我怎样才能知道该链中的一部分是unvalid?有没有什么办法
知道什么是缺少的一部分?




好了,从我的经验,如果你打开你的密钥库并查看它,你应该看到您的证书显然形成了一个链条。我不知道你用什么工具来查看您的密钥库(或者您使用Windows密钥库),但是当你查看你的钥匙,你应该看到某种形式的链条。如果链是正确形成,它会正确显示,并且没有任何缺失的部分。



我的猜测是,当您导入证书回复,这没' ŧ形成链条的某些原因。换句话说,你的证书是在你的密钥库作为奔放的公共密钥。


For an application, I need to have a SSL certificate for a WCF service,

So we installed it. If I go with an internet browser with a web browser trough https, I've got no problem, no warning, nothing, so I suppose that this certificate is considered as valid for windows.

The problem is that when I'm trying to connect to my WCF server, I got this error:

The X.509 certificate CN=myHostName, OU=tom, O=myDomainName,

L=MyLocation, S=SO, C=CH chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The revocation function was unable to check revocation because the revocation server was offline.

What can be wrong? How can I know which part of the chain is unvalid? Is there any way to know what is the missing part?

Here is my code The server:

ServiceHost myHost = new ServiceHost(typeof(MyService));
WSHttpBinding binding = new WSHttpBinding
{
    ReaderQuotas = { MaxStringContentLength = int.MaxValue, MaxArrayLength = int.MaxValue, MaxDepth = int.MaxValue, MaxBytesPerRead = int.MaxValue, MaxNameTableCharCount = int.MaxValue },
    MaxReceivedMessageSize = int.MaxValue
};
TimeSpan timeoutSpan = TimeSpan.FromMilliseconds(timeout);
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;

binding.MaxBufferPoolSize = int.MaxValue;

//we set the security type
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

//we set the server's certificate
myHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, ConfigurationManager.AppSettings["Hostname"]);
myHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
//we add the endPoint(and we indicate which methods are exposed through the interface

myHost.AddServiceEndpoint(services[port], binding,                  String.Format("http://localhost:{0}", port));




//Some services doesn't need an authentication
if (!servicesWithoutAuth.Contains(services[port]))
{
    //We set the authentifier:
    myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
    myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();
    myHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;


    //we set the AuthorizationPolicy
    List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy> { new CustomAuthorizationPolicy() };
    myHost.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly();
}
else
{
    //We set the authentifier:
    myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
    myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new NoUserNamePasswordValidator();
}

//We bypass the certificate verification(our certificate is only self signed)
//HACK Only to desactivate the SSL check: 
ServicePointManager.ServerCertificateValidationCallback += ValidateCertificate;



//HACK: Remove when debug finished
private static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
{
    return true;
}

My client side:

// the remote adress is of the form "net.tcp://localhost:8000"
string remoteAddress = String.Format("{0}://{1}:{2}", Tools.GetDescription(accessInfo.ServiceHost.Protocol), accessInfo.ServiceHost.HostName, accessInfo.PortNumber);

// HACK: binding depends on protocol -> switch over accessInfo.ServiceHost.Protocol

// avoid seralization/deserialization problems with large XML's
WSHttpBinding binding = new WSHttpBinding();
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.ReaderQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
TimeSpan timeoutSpan = DateTime.Now.AddMinutes(30) - DateTime.Now;
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;


//++
binding.MaxBufferPoolSize = int.MaxValue;

//we set the security type
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

ChannelFactory<TService> channelFactory = new ChannelFactory<TService>(binding, remoteAddress);

channelFactory.Credentials.UserName.UserName = ((UsernamePasswordAuthentication)authInfos).Username;
channelFactory.Credentials.UserName.Password = ((UsernamePasswordAuthentication)authInfos).Password;


//We set the maxItemsInObjectGraph
foreach (OperationDescription op in channelFactory.Endpoint.Contract.Operations)
{
    DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
    if (dataContractBehavior != null)
    {
        dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
    }
}
SamlSecurityTokenAuthenticator authenticator = new SamlSecurityTokenAuthenticator(new List<SecurityTokenAuthenticator>(new SecurityTokenAuthenticator[] { new RsaSecurityTokenAuthenticator(), new X509SecurityTokenAuthenticator(X509CertificateValidator.None) }), TimeSpan.FromDays(5));

_service = channelFactory.CreateChannel();

解决方案

How can I know which part of the chain is unvalid? Is there any way to know what is the missing part?

Well, from my experience, if you open your keystore and view it, you should see that your certificate clearly forms a chain. I don't know what tool you use to view your keystore (or if your using the windows keystore), but when you view your key, you should see a chain of some kind. If a chain is formed correctly, it will appear correctly, and doesn't have any missing parts.

My guess is that when you imported your certificate reply, it didn't form the chain for some reason. In other words, your certificate is in your keystore as a "unchained" public key.

这篇关于利用企业CA WCF SSL证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆