2009-05-21 6 views
9

स्पष्ट रूप से मैं अपने पिछले पोस्ट में गलत सवाल पूछ रहा था। मेरे पास एक सुरक्षित वेब साइट (https://..) के रूप में चल रहे X.50 9 प्रमाण पत्र के साथ सुरक्षित एक वेब सेवा है। मैं कंपनी के रूट सीए द्वारा जारी किए गए क्लाइंट के मशीन सर्टिफिकेट (X.50 9) का उपयोग करना चाहता हूं ताकि सर्वर को सत्यापित किया जा सके कि क्लाइंट मशीन सेवा का उपयोग करने के लिए अधिकृत है। ऐसा करने के लिए, मुझे प्रमाण पत्र का निरीक्षण करने और कुछ पहचान करने वाली सुविधा की आवश्यकता है और डेटाबेस में संग्रहीत मूल्य (शायद थंबप्रिंट?) से मेल खाना चाहिए। , तबमैं वेब सेवा में क्लाइंट से भेजे गए X509 प्रमाणपत्र कैसे प्राप्त करूं?

public static class SecurityCertificate 
{ 
    private static X509Certificate2 _certificate = null; 

    public static X509Certificate2 Certificate 
    { 
     get { return _certificate; } 
    } 

    public static bool LoadCertificate() 
    { 
     // get thumbprint from app.config 
     string thumbPrint = Properties.Settings.Default.Thumbprint; 
     if (string.IsNullOrEmpty(thumbPrint)) 
     { 
      // if no thumbprint on file, user must select certificate to use 
      _certificate = PickCertificate(StoreLocation.LocalMachine, StoreName.My); 
      if (null != _certificate) 
      { 
       // show certificate details dialog 
       X509Certificate2UI.DisplayCertificate(_certificate); 
       Properties.Settings.Default.Thumbprint = _certificate.Thumbprint; 
       Properties.Settings.Default.Save(); 
      } 
     } 
     else 
     { 
      _certificate = FindCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, thumbPrint); 
     } 

     if (null == _certificate) 
     { 
      MessageBox.Show("You must have a valid machine certificate to use STS."); 
      return false; 
     } 

     return true; 
    } 

    private static X509Certificate2 PickCertificate(StoreLocation location, StoreName name) 
    { 
     X509Store store = new X509Store(name, location); 
     try 
     { 
      // create and open store for read-only access 
      store.Open(OpenFlags.ReadOnly); 

      X509Certificate2Collection coll = store.Certificates.Find(X509FindType.FindByIssuerName, STSClientConstants.NBCCA, true); 
      if (0 == coll.Count) 
      { 
       MessageBox.Show("No valid machine certificate found - please contact tech support."); 
       return null; 
      } 

      // pick a certificate from the store 
      coll = null; 
      while (null == coll || 0 == coll.Count) 
      { 
       coll = X509Certificate2UI.SelectFromCollection(
         store.Certificates, "Local Machine Certificates", 
         "Select one", X509SelectionFlag.SingleSelection); 
      } 

      // return first certificate found 
      return coll[ 0 ]; 
     } 
     // always close the store 
     finally { store.Close(); } 
    } 

    private static X509Certificate2 FindCertificate(StoreLocation location, StoreName name, X509FindType findType, string findValue) 
    { 
     X509Store store = new X509Store(name, location); 
     try 
     { 
      // create and open store for read-only access 
      store.Open(OpenFlags.ReadOnly); 

      // search store 
      X509Certificate2Collection col = store.Certificates.Find(findType, findValue, true); 

      // return first certificate found 
      return col[ 0 ]; 
     } 
     // always close the store 
     finally { store.Close(); } 
    } 

मैं thusly आउटबाउंड धारा को प्रमाण पत्र देते हैं:

यहाँ कोड मैं स्थानीय प्रमाणपत्र संग्रह से प्रमाण पत्र प्राप्त करने के लिए उपयोग है (http://msdn.microsoft.com/en-us/magazine/cc163454.aspx से सीधे उठा लिया)

public static class ServiceDataAccess 
{  
    private static STSWebService _stsWebService = new STSWebService(); 

    public static DataSet GetData(Dictionary<string,string> DictParam, string action) 
    { 
     // add the machine certificate here, the first web service call made by the program (only called once) 
     _stsWebService.ClientCertificates.Add(SecurityCertificate.Certificate); 
     // rest of web service call here... 
    } 
} 

मेरा सवाल यह है - मैं वेब सेवा कोड में प्रमाणपत्र कैसे प्राप्त करूं? अधिकांश नमूना कोड स्निपेट्स मैं उस कवर में आया हूं कि कस्टम सत्यापन कैसे करें, वहां GetCertificate() कॉल है, जाहिर है कि यह मानना ​​इतना आसान है कि हर किसी को यह जानना चाहिए कि इसे कैसे करना है?

मेरा मुख्य वर्ग वेब सेवा से प्राप्त होता है, इसलिए मैं प्रमाण पत्र प्राप्त करने के लिए Context.Request.ClientCertificate का उपयोग कर सकता हूं, लेकिन यह एक HttpClientCertificate है, X509Certificate2 नहीं। HttpContext मुझे एक ही परिणाम देता है। सत्यापन के लिए एक कस्टम सी # विधि को कॉल करने के तरीके के बारे में कोई संकेत नहीं के साथ, अन्य दृष्टिकोण सभी वेब कॉन्फ़िगरेशन कोड का उपयोग पूर्व परिभाषित सत्यापन कोड को कॉल करने के लिए करते हैं।

मुझे यकीन है कि यह एक और "बेवकूफ सवाल" है कि कोई वापस आकर कहेंगे "देखो, बस यह करें और यह काम करता है," लेकिन यह ठीक है। मैंने इसे काम करने के लिए कई घंटे बिताए हैं, और इस बिंदु पर मेरा गौरव लगभग कोई नहीं है। क्या कोई मुझे मेरे तरीकों की त्रुटि दिखा सकता है?

धन्यवाद, डेव

+0

यदि आपके पास HttpContext नहीं है, तो http: // stackoverflow के लिए उत्तर देखें।कॉम/प्रश्न/7528455/कैसे-से-get-the-x509certificate-from-a-client-request? lq = 1 –

उत्तर

12

मैं कुछ इसी तरह, अपने समय हो गया लेकिन कर याद करते हैं हुक, आप अपने वेब सेवा में इस की कोशिश की है:

X509Certificate2 cert = new X509Certificate2(Context.Request.ClientCertificate.Certificate); 
+0

यह काम करता है! अब मैं अंततः अपनी समस्या के मांस तक पहुंच सकता हूं - यह पता लगा रहा हूं कि डेटाबेस में संग्रहीत मूल्य के साथ मिलान करने के लिए मैं किस मूल्य का उपयोग कर सकता हूं ... धन्यवाद !! – DaveN59

+1

थंबप्रिंट का उपयोग करने के लिए ठीक है अगर आप अपने डेटाबेस को विश्वसनीय प्राधिकारी के रूप में देख रहे हैं, तो मैंने इस दृष्टिकोण को लेने वाले ऐप्स पर काम किया है। ओटीओएच, यदि आपको एक वितरित ट्रस्ट मॉडल (सीएएस का उपयोग करके) की आवश्यकता है, तो आपको अतिरिक्त चेक (उदा। प्रमाण पत्र सत्यापित करना) की आवश्यकता है। – DSO

+0

मुझे लगता है कि मैंने बहुत जल्द काम किया होगा। थंबप्रिंट तक पहुंचने का प्रयास करने से अपवाद 'सिस्टम.Security.Cryptography.CryptographicException' - तो, ​​भले ही http प्रमाणपत्र अब X509Certificate2 प्रकार का है, क्या यह वास्तव में क्लाइंट से भेजा गया प्रमाण पत्र है, या मैंने अभी एक नया बनाया है जानवर जो बस थोड़े दिखता है? – DaveN59

1

आप अपने आप में ServicePointManager.ServerCertificateValidationCallback देख http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.servercertificatevalidationcallback.aspx

+0

मैंने इसके साथ-साथ कई संदर्भ भी देखे। यह सर्वर प्रमाण पत्र मान्य करता है, ग्राहक प्रमाण पत्र नहीं। – DaveN59

1

प्रमाण पत्र को किसी उपयोगकर्ता को वापस कैसे बांधें, इस विषय पर कि कुंजी से जुड़े उपयोगकर्ता की पहचान अच्छी है (क्योंकि प्रमाण पत्र को एक विश्वसनीय रूट पर वापस सत्यापित किया गया है और बी नहीं है ईन निरस्त कर दिया गया) तो आपको किसी उपयोगकर्ता को प्रमाण द्वारा दावा की गई पहचान को बांधने की आवश्यकता है। आप विषय डीएन के एलडीएपी स्ट्रिंग फॉर्म का उपयोग कर सकते हैं और स्थानीय आईडी निर्धारित करने के लिए इसे ऊपर (सीएन = उपयोगकर्ता नाम, कहां = विभाग ...) देख सकते हैं। कार्ड की हानि या सर्टिफिकेट की प्राकृतिक समाप्ति के कारण उपयोगकर्ता अपने कुंजी/प्रमाण पत्र को फिर से उत्पन्न करने के मामले में यह लचीला है। यह इस तथ्य पर निर्भर करता है कि दो सीए दो विषयों के साथ दो अलग-अलग लोगों को दो विषय जारी नहीं करेंगे।

यदि प्रमाणपत्र एमएस सीए द्वारा जारी किया गया था तो इसमें यूपीएन हो सकता है जो प्रभावी रूप से एक डोमेन लॉगऑन नाम है।

वैकल्पिक रूप से यदि आप किसी वास्तविक प्रमाणपत्र में उपयोगकर्ता की पहचान को जोड़ना चाहते हैं तो सामान्य विधि जारीकर्ता नाम और प्रमाणपत्र सीरियल नंबर को संग्रहीत करना है। सीए को प्रत्येक प्रमाणपत्र के लिए अद्वितीय सीरियल नंबर जारी करना होगा। नोट सीरियल नंबर सीए के आधार पर बड़ा हो सकता है। हालांकि इस विधि का उपयोग करने का मतलब यह नहीं है कि उपयोगकर्ता प्रमाण को फिर से जारी किए जाने पर डेटाबेस में प्रमाणपत्र विवरण अपडेट किया जाना चाहिए।

+1

उत्कृष्ट जानकारी! अगर मैं अभी भी परियोजना पर काम कर रहा था, तो यह वास्तव में ऐसी जानकारी है जिसे मैंने पहले कार्यान्वयन में बनाई गई समस्याओं को ठीक करने की आवश्यकता होगी। हालांकि, चूंकि अब मैं अलग-अलग जिम्मेदारियों के साथ एक अलग कंपनी में स्थानांतरित हो गया हूं, इसलिए मैं इसे किसी और के लिए अभ्यास के रूप में छोड़ दूंगा ... प्रतिक्रिया के लिए धन्यवाद! – DaveN59