2010-09-24 6 views
22

मेरा एप्लिकेशन (.net 3.5 sp1) विभिन्न अंतराल के साथ संवाद करने के लिए HttpWebRequest का उपयोग करता है, कभी-कभी इसके ऊपर HTTPS पर जहां प्रत्येक होस्टिंग सर्वर के पास एक अलग सुरक्षा प्रोटोकॉल आवश्यकता हो सकती है टीएलएस या एसएसएल 3 या तो कहें।प्रति अनुरोध .net HttpWebRequest पर सुरक्षाप्रोटोकॉल (एसएसएल 3 या टीएलएस) सेट करें

आम तौर पर सर्वर सुरक्षाप्रॉटोकॉल को टीएलएस या एसएसएल 3 का उपयोग करने के लिए अच्छा और खुशी से वार्तालाप/फॉलबैक खेलते हैं, लेकिन कुछ नहीं करते हैं और जब टीनेट या एसएसएल 3 (डिफ़ॉल्ट मुझे लगता है) के रूप में सेट किया जाता है तो वे सर्वर जो केवल समर्थन करते हैं एक त्रुटि त्रुटि फेंकने के लिए SSL3 कारण .net।

जो मैं बता सकता हूं उससे .net एक सुरक्षा सुरक्षा प्रोटोकॉल के साथ ServicePointManager ऑब्जेक्ट प्रदान करता है जिसे TLS, SSL3 या दोनों पर सेट किया जा सकता है। इसलिए आदर्श रूप से जब दोनों विचारों पर सेट किया जाता है तो क्लाइंट और सर्वर को क्या उपयोग करना चाहिए, इस बारे में बातचीत करनी चाहिए, लेकिन जैसा कि पहले बताया गया था कि काम नहीं लगता है।

माना जाता है कि आप ServicePointManager.SecurityProtocol = Ssl3 सेट कर सकते हैं लेकिन टीएलएस का उपयोग करने वाले एंडपॉइंट्स के बारे में क्या?

सेवापॉइंटमैनेजर और सुरक्षाप्रोटोकॉल के साथ जो समस्या मैं देखता हूं वह यह है कि इसकी स्थिर और इसलिए अनुप्रयोग डोमेन विस्तृत है।

सवाल का

तो ..

कैसे मैं एक अलग SecurityProtocol साथ HttpWebRequest उदा का उपयोग कर के बारे में जाना होगा

1) यूआरएल 1 टीएलएस का उपयोग करने के लिए सेट। SSL3 (बातचीत)

2) यूआरएल SSL3 करने के लिए 2 सेट (SSL3 केवल)

उत्तर

11

दुर्भाग्य से, यह आप की तरह लगती सेवा बिंदु प्रति इस अनुकूलित कर सकते हैं। मैं सुझाव दूंगा कि आप इस क्षेत्र के लिए एमएस कनेक्ट वेबसाइट पर एक फीचर अनुरोध दर्ज करें।

एक गंदे कामकाज के रूप में, आप उन साइटों को निष्पादित करने का प्रयास कर सकते हैं जिनके लिए एक नए एपडोमेन में एक अलग सुरक्षा प्रोटोकॉल की आवश्यकता होती है। स्टेटिक उदाहरण प्रति एपडोमेन हैं, जिससे आपको अलगाव की आवश्यकता हो।

+0

मेरे डर की पुष्टि करने के लिए धन्यवाद, उम्मीद कर रहा था कि यह मामला नहीं होगा। – Rich

+4

एमएस कनेक्ट अनुरोध https://connect.microsoft.com/VisualStudio/feedback/details/605185/cant-set-the-security-protocol-per-servicepoint की स्थिति "ठीक नहीं होगी" –

+0

@MichaelFreidgeim यदि अभी देखो , माइक्रोसॉफ्ट ने यह समझाया है कि इसे नेट फ्रेमवर्क 4.7.1 - * में तय किया जाएगा। ".NET Framework 4.7.1 की आगामी रिलीज में, हमने HttpClientHandler क्लास में नई गुण जोड़े हैं जो System.Net.HttpClient में उपयोग की जाती हैं। यह HttpWebRequest की बजाय HTTP अनुरोधों के लिए उपयोग करने के लिए पसंदीदा एपीआई है। इन नए गुणों को .NET कोर 2.0 रिलीज से मेल करने के लिए जोड़ा गया था, जिनके पास पहले से ही HttpClientHandler पर नए गुण हैं। "* – Lankymart

4

this answer के अनुसार, सुरक्षाप्रोटोकॉल सेटिंग वास्तव में प्रति-ऐपडोमेन है, इसलिए यदि आप इसे काम करने के लिए दृढ़ हैं, तो अलग-अलग सेटिंग्स के लिए अलग-अलग ऐपडोमेन बनाएं, और अपने प्रश्नों को मार्शल करें।

बिल्कुल एक "साफ" समाधान नहीं है, लेकिन हो सकता है कि आप तीसरे पक्ष के पुस्तकालयों का उपयोग किए बिना केवल वही कर सकें जो आपको संभव हो।

9

मेरे पास एक ही समस्या थी और प्रॉक्सी क्लास लिखा था, जो स्थानीयहोस्ट पर बंदरगाह खोलता है और आगे के सभी होस्ट या निर्दिष्ट पोर्ट को पोर्ट करता है।

तो कनेक्शन इस

[अपने कोड] की तरह हो जाता है --- HTTP ---> [स्थानीय होस्ट पर प्रॉक्सी: पोर्ट] --- HTTPS ---> [वेब साइट]

में तथ्य यह SSL/TLS न सिर्फ HTTP

using System; 
using System.IO; 
using System.Net; 
using System.Net.Security; 
using System.Net.Sockets; 
using System.Security.Authentication; 
using System.Security.Cryptography.X509Certificates; 

namespace System 
{ 
    class sslProxy : IDisposable 
    { 
     readonly string host; 
     readonly int port; 
     readonly TcpListener listener; 
     readonly SslProtocols sslProtocols; 
     bool disposed; 
     static readonly X509CertificateCollection sertCol = new X509CertificateCollection(); 
     public sslProxy(string url, SslProtocols protocols) 
     { 
      var uri = new Uri(url); 
      host = uri.Host; 
      port = uri.Port; 
      sslProtocols = protocols; 
      listener = new TcpListener(IPAddress.Loopback, 0); 
      listener.Start(); 
      listener.BeginAcceptTcpClient(onAcceptTcpClient, null); 
      Proxy = new WebProxy("localhost", (listener.LocalEndpoint as IPEndPoint).Port); 
     } 
     public WebProxy Proxy 
     { 
      get; 
      private set; 
     } 
     class stBuf 
     { 
      public TcpClient tcs; 
      public TcpClient tcd; 
      public Stream sts; 
      public Stream std; 
      public byte[] buf; 
      public stBuf dup; 
     } 
     void onAcceptTcpClient(IAsyncResult ar) 
     { 
      if (disposed) return; 
      var tcl = listener.EndAcceptTcpClient(ar); 
      TcpClient tcr = null; 
      try 
      { 
       listener.BeginAcceptTcpClient(onAcceptTcpClient, null); 
       var nsl = tcl.GetStream(); 

       tcr = new TcpClient(host, port); 
       Stream nsr = tcr.GetStream(); 
       if (sslProtocols != SslProtocols.None) 
       { 
        var sss = new SslStream(nsr, true); 
        sss.AuthenticateAsClient(host, sertCol, sslProtocols, false); 
        nsr = sss; 
       } // if 

       var sts = new stBuf() { tcs = tcl, sts = nsl, tcd = tcr, std = nsr, buf = new byte[tcl.ReceiveBufferSize] }; 
       var std = new stBuf() { tcs = tcr, sts = nsr, tcd = tcl, std = nsl, buf = new byte[tcr.ReceiveBufferSize] }; 
       sts.dup = std; 
       std.dup = sts; 

       nsl.BeginRead(sts.buf, 0, sts.buf.Length, onReceive, sts); 
       nsr.BeginRead(std.buf, 0, std.buf.Length, onReceive, std); 
      } // try 
      catch 
      { 
       tcl.Close(); 
       if (tcr != null) tcr.Close(); 
      } // catch 
     } 
     void close(stBuf st) 
     { 
      var dup = st.dup; 
      if (dup != null) 
      { 
       dup.dup = st.dup = null; 
       st.sts.Dispose(); 
       st.std.Dispose(); 
      } // if 
     } 
     void onReceive(IAsyncResult ar) 
     { 
      var st = ar.AsyncState as stBuf; 
      try 
      { 
       if (!(st.dup != null && st.tcs.Connected && st.sts.CanRead && !disposed)) { close(st); return; }; 
       var n = st.sts.EndRead(ar); 
       if (!(n > 0 && st.tcd.Connected && st.std.CanWrite)) { close(st); return; }; 
       st.std.Write(st.buf, 0, n); 
       if (!(st.tcs.Connected && st.tcd.Connected && st.sts.CanRead && st.std.CanWrite)) { close(st); return; }; 
       st.sts.BeginRead(st.buf, 0, st.buf.Length, onReceive, st); 
      } // try 
      catch 
      { 
       close(st); 
      } // catch 
     } 
     public void Dispose() 
     { 
      if (!disposed) 
      { 
       disposed = true; 
       listener.Stop(); 
      } // if 
     } 
    } 
} 

के उपयोग का उदाहरण

// create proxy once and keep it 
// note you have to mention :443 port (https default) 
// ssl protocols to use (enum can use | or + to have many) 
var p = new sslProxy("http://www.google.com:443", SslProtocols.Tls); 
// using our connections 
for (int i=0; i<5; i++) 
{ 
    // url here goes without https just http 
    var rq = HttpWebRequest.CreateHttp("http://www.google.com/") as HttpWebRequest; 
    // specify that we are connecting via proxy 
    rq.Proxy = p.Proxy; 
    var rs = rq.GetResponse() as HttpWebResponse; 
    var r = new StreamReader(rs.GetResponseStream()).ReadToEnd(); 
    rs.Dispose(); 
} // for 
// just dispose proxy once done 
p.Dispose(); 
+0

यह कैसे अधिक वोट प्राप्त नहीं हुआ है या नहीं जवाब के रूप में बंद नहीं किया गया है? मैंने अभी तक यह कोशिश नहीं की है, लेकिन @ k010mb0 क्या आप इसका उत्तर मानेंगे? यह एक उच्च प्रदर्शन वेब अनुप्रयोग सेटिंग में कैसे करता है? – kstubs

+0

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

0

आप एक कर सकते हैं में किसी भी प्रोटोकॉल रैप करने के लिए इस्तेमाल किया जा सकता सभी अंतर्निहित कनेक्शन को बंद करने और एक नया हैंडशेक मजबूर करने के लिए इस कोड द्वारा इस पर छेड़छाड़ करें।

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); 
... 
... 
... 
request.ServicePoint.CloseConnectionGroup(request.ConnectionGroupName); 
0

आप HttpWebRequests बनाने के लिए एक स्थिर उपयोगिता विधि के साथ एक HttpWebRequest "उपयोगिता वर्ग" बना सकता है। स्थिर उपयोगिता विधि में ServicePointManager.SecurityProtocol को सेट करने और एक विशेष HttpWebRequest बनाने के आसपास सी # लॉक स्टेटमेंट का उपयोग करें। लॉक स्टेटमेंट एक ही कोड को उसी कोड को निष्पादित करने के लिए एक ही ऐपडोमेन से अन्य धागे को रोकता है, इस प्रकार आपके द्वारा सेट किए गए टीएलएस प्रोटोकॉल को तब तक नहीं बदला जाएगा जब तक कि संपूर्ण लॉक ब्लॉक (= महत्वपूर्ण अनुभाग) निष्पादित नहीं किया जाता है।

लेकिन वास्तव में उच्च निष्पादन अनुप्रयोगों (अत्यधिक उच्च प्रदर्शन करने के लिए) के लिए जागरूक है, इस अनुमोदन का नकारात्मक प्रदर्शन प्रभाव हो सकता है।

3

हमारे कुछ विक्रेताओं ने एसएसएल 3 के लिए समर्थन बंद कर दिया है, जबकि अन्य इसे विशेष रूप से उपयोग करते हैं, हमारे सिस्टम में कई समस्याएं दिखाई देती हैं जिन्हें इस प्रश्न से कार्यक्षमता के साथ हल किया जा सकता है। लेकिन छह साल बाद, हमने अभी भी इसे हासिल करने के लिए तंत्र में नहीं बनाया है।

System.Net.ServicePointManager.SecurityProtocol = 
    System.Net.SecurityProtocolType.Ssl3 
    | System.Net.SecurityProtocolType.Tls12 
    | SecurityProtocolType.Tls11 
    | SecurityProtocolType.Tls; 
0

सेट यह सब: हमारे वैकल्पिक हल स्पष्ट रूप से सुरक्षा प्रोटोकॉल है कि इस तरह सभी स्थितियों का समर्थन करेंगे, परिभाषित करने के लिए है। मेरे आवेदन में यह विभिन्न सुरक्षा प्रोटोकॉल के लिए काम है।

System.Net.ServicePointManager.SecurityProtocol = 
System.Net.SecurityProtocolType.Ssl3 
| System.Net.SecurityProtocolType.Tls12 
| SecurityProtocolType.Tls11 
| SecurityProtocolType.Tls; 
+1

यह दो अलग-अलग यूआरएल के लिए विभिन्न सुरक्षा प्रोटोकॉल का उपयोग करने के सवाल के जवाब में प्रकट नहीं होता है। – Loren

संबंधित मुद्दे