我要求确保客户端在WCF会话期间提供的x509证书在其链中具有特定的证书颁发机构。
我知道我可以使用ChainElements [index]以编程方式检查证书链。
但我不确定如何在使用配置文件与WCF集成的同时执行此操作。
目前,WCF在配置文件中设置,见下文:
<services>
<service name="SampleService" behaviorConfiguration="wsHttpBehavior">
<endpoint name="SampleEndPoint"
address="http://localhost:70000/SampleService.svc"
binding="wsHttpBinding"
bindingConfiguration="wsHttpBinding"
contract="SampleApp.ISampleService">
</endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding">
<reliableSession enabled="true" ordered="true" />
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHittpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="aa aa aa"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySerialNumber" />
</serviceCredentials>
<serviceBehaviors>
</behaviors>
我可以在配置文件中做些什么来告诉它确保提供的客户端证书包含特定的证书颁发机构。或者我是否必须绑定到WCF频道才能完成此操作?它甚至可能吗?
答案 0 :(得分:1)
这可以通过WCF的可扩展性(Introduction to Extensbility)完成。
具体示例(How to: Createa Service that Employs a Custom Certificate Validator)
使用该信息和我从this StackoverFlow post收集的信息,我创建了一项服务,检查证书的有效性,并验证证书来自特定的证书颁发机构。
代码:
public class CustomX509CertificateValidator : X509CertificateValidator
{
public override void Validate(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
{
var ch = new X509Chain();
//RevocationMode Enumeration
//http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509revocationmode.aspx
ch.ChainPolicy.RevocationMode = X509RevocationMode.Online;
//RevocationFlag Enumeration
//http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509revocationflag.aspx
ch.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
//The time span that elapsed during online revocation verification or downloading the
//certificate revocation list (CRL)
ch.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(1000);
//VerificationFlags Enumeration
//http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509verificationflags.aspx
ch.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
//The time that the certificate was verified expressed in local time
ch.ChainPolicy.VerificationTime = DateTime.Now;
ch.Build(certificate);
//Check to see if the CA is a specific one
if (ch.ChainElements[ch.ChainElements.Count - 1].Certificate.IssuerName.Name != "CN=Something, OU=PKI...,")
{
throw new SecurityTokenValidationException("Certificate was not issued by a trusted issuer");
}
foreach (X509ChainStatus s in ch.ChainStatus)
{
string str = s.Status.ToString();
Console.WriteLine("str: " + str);
}
//Check to see if the current certificate is revoced in the current system (does this not happen in the above?
X509Store store = new X509Store(StoreName.Disallowed, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
bool isRevoked = store.Certificates.Contains(certificate);
store.Close();
if (isRevoked)
{
throw new SecurityTokenValidationException("Certificate is revoked");
}
if (certificate.Verify() == false)
{
throw new SecurityTokenValidationException("Certificate cannot be verified");
}
}
}
的web.config
<behaviors>
<serviceBehaviors>
<behavior name="secureHttpBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<serviceCertificate findValue="00 b7 70" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/>
<clientCertificate>
<authentication certificateValidationMode="Custom"
customCertificateValidatorType="WcfWebServer.CustomX509CertificateValidator, WcfWebServer"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>