2011-08-10 39 views
1

我正在構建一個基於WCF的應用程序,其中用戶在智能卡上使用證書進行身份驗證。該服務託管在IIS7上,客戶端是Windows窗體應用程序。防止IIS7中的WCF緩存身份驗證證書

問題是,當添加新用戶(新證書創建)時,用戶無法登錄,直到IIS重新啓動或應用程序池被回收。如果現有用戶被刪除,他也可以登錄,直到重新啓動/回收。

在我的行爲定義我有

 <serviceCredentials> 
      <serviceCertificate findValue="blahblah.local" 
    x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" /> 
      <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" 
    membershipProviderName="SqlMembershipProvider" cacheLogonTokens="true"/> 
      <clientCertificate> 
       <authentication mapClientCertificateToWindowsAccount="true" 
certificateValidationMode="ChainTrust" revocationMode="Online"/> 
      </clientCertificate> 
     </serviceCredentials> 

有什麼辦法防止這種證書「緩存」的發生或刷新按需激活證書列表?

+0

你如何添加新證書/客戶? –

回答

0

顯然,緩存是System.Identitymodel的已知「特徵」。這是討論here和更多信息可用here

我所做的就是使用一個自定義的驗證器(代碼如下)來處理這個問題。

編輯:增加更多的代碼在實時對CRL的驗證X.509證書here

的web.config

<clientCertificate> 
    <authentication mapClientCertificateToWindowsAccount="true" certificateValidationMode="Custom" customCertificateValidatorType="My.IdentityModel.MyX509Validator, My.IdentityModel" /> 
</clientCertificate> 

代碼

using System; 
using System.IO; 
using System.IdentityModel.Selectors; 
using System.IdentityModel.Tokens; 
using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 

namespace My.IdentityModel 
{ 
    /// <summary> 
    /// Custom X.509 certificate validator 
    /// Richard Ginzburg - richard (at) ginzburgconsulting (dot) com 
    /// </summary> 
    public class MyX509Validator : X509CertificateValidator 
    { 
     public override void Validate(X509Certificate2 certificate) 
     { 
      if (certificate == null) 
      { 
       throw new ArgumentNullException("certificate", "Certificate validation failed, no certificate provided"); 
      } 

      X509ChainPolicy myChainPolicy = new X509ChainPolicy 
               { 
                RevocationMode = X509RevocationMode.Online, 
                RevocationFlag = X509RevocationFlag.EntireChain, 
                VerificationFlags = X509VerificationFlags.NoFlag, 
                UrlRetrievalTimeout = new TimeSpan(0, 0, 10), 
                VerificationTime = DateTime.Now 
               }; 
      X509Chain chain = new X509Chain(true) {ChainPolicy = myChainPolicy}; 

      try 
      { 
       bool ok = chain.Build(certificate); 
       if(!ok) 
       { 
        foreach (var status in chain.ChainStatus) 
        { 
         Logging.Log("MyX509Validator: Validation failed - " + status.StatusInformation); 
        } 
        throw new SecurityTokenValidationException("Certificate validation failed when building chain"); 
       } 
      } 
      catch (CryptographicException e) 
      { 
       throw new SecurityTokenValidationException("Certificate validation failed when building chain, " + e); 
      } 
     } 
    } 
}