HttpClient का उपयोग करके Https कॉल करें


157

मैं HttpClientC # का उपयोग करके WebApi कॉल करने के लिए उपयोग कर रहा हूं । की तुलना में साफ और तेज तरीका लगता है WebClient। हालांकि मैं Httpsकॉल करते समय फंस गया हूं ।

मैं Httpsकॉल करने के लिए नीचे दिए गए कोड को कैसे बना सकता हूं ?

HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://foobar.com/");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/xml"));

var task = httpClient.PostAsXmlAsync<DeviceRequest>(
                "api/SaveData", request);

EDIT 1: उपरोक्त कोड http कॉल करने के लिए ठीक काम करता है। लेकिन जब मैं इस योजना को https में बदलता हूं तो यह काम नहीं करता है। यहाँ त्रुटि प्राप्त की गई है:

अंतर्निहित कनेक्शन बंद कर दिया गया था: एसएसएल / टीएलएस सुरक्षित चैनल के लिए विश्वास संबंध स्थापित नहीं कर सका।

EDIT 2: इस योजना को https में बदलना है: चरण एक।

मैं C # अनुरोध के साथ प्रमाण पत्र और सार्वजनिक / निजी कुंजी की आपूर्ति कैसे करूं


2
आप केवल निर्दिष्ट करके https कॉल कर रहे हैंnew Uri("https://foobar.com/");
felickz

2
मैं उलझन में हूं। क्या वह पहले से काम नहीं करता है? क्या आपको कोई त्रुटि हो रही है? (संपादित करें: ओपी को https से http में बदलने से पहले प्रकाशित किया गया था)
टिम

जवाबों:


215

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

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

अपने उदाहरण कोड को संशोधित करना, यह होगा

HttpClient httpClient = new HttpClient();   

//specify to use TLS 1.2 as default connection
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

httpClient.BaseAddress = new Uri("https://foobar.com/");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

var task = httpClient.PostAsXmlAsync<DeviceRequest>("api/SaveData", request);

@ डेरेक खुश हैं और आपका स्वागत है। यदि किसी कारण से, आप उत्पादन सेटिंग में कोड को संशोधित नहीं कर सकते हैं, लेकिन सर्वर पर कुछ व्यवस्थापक करने में सक्षम हैं, तो मैं इस उपयोगिता का उपयोग टीएलएस 1.2 को डिफ़ॉल्ट रूप से कॉन्फ़िगर करने के लिए करता हूं। nartac.com/Products/IISCrypto
रोनाल्ड रामोस

SecurityProtocolType.Tls12आपके द्वारा उल्लिखित उन मानों को नहीं पाया जा सकता है
JobaDiniz

1
@JOBDiniz .NET 4.5 या उच्चतर का उपयोग करता है और इसमें System.Net नामस्थान शामिल है।
रोनाल्ड रामोस

क्या SecurityProtocol को सेट करना केवल एक बार होने की आवश्यकता है? एप्लिकेशन स्टार्टअप पर पसंद है?
कैमहार्ट

यह बहुत अच्छा काम करता है। धन्यवाद। मैंने यह भी पाया कि मुझे इस HttpClient क्लाइंट = नए HttpClient () का उपयोग करने वाले किसी भी हेडर को साफ़ करने की आवश्यकता नहीं है; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; HttpResponseMessage response = wait client.GetAsync ("https: // ...") का इंतजार करें;
AtLeastTheresTast

127

यूटीआई में केवल एचटीटीपीएस निर्दिष्ट करें।

new Uri("https://foobar.com/");

Foobar.com को एक विश्वसनीय एसएसएल प्रमाणपत्र की आवश्यकता होगी या आपकी कॉल अविश्वसनीय त्रुटि के साथ विफल हो जाएगी।

EDIT उत्तर: HttpClient के साथ क्लाइंट सर्टिफिकेट

WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 certificate = GetMyX509Certificate();
handler.ClientCertificates.Add(certificate);
HttpClient client = new HttpClient(handler);

EDIT Answer2: यदि आप जिस सर्वर से कनेक्ट हो रहे हैं, वह SSL, TLS 1.0 और 1.1 को निष्क्रिय कर चुका है और आप अभी भी .NET फ्रेमवर्क 4.5 (या नीचे) चला रहे हैं, तो आपको चुनाव करने की आवश्यकता है

  1. .Net 4.6+ पर अपग्रेड करें ( डिफ़ॉल्ट रूप से TLS 1.2 का समर्थन करता है )
  2. TLS1.2 से कनेक्ट करने के लिए 4.5 को निर्देश देने के लिए रजिस्ट्री में बदलाव जोड़ें (देखें: कंपास और राइट्स के लिए सेल्सफोर्स राइटअप को बदलने या चेकआउट करने के लिए IISCrypto रोनाल्ड रामोस की टिप्पणियों को देखें )
  3. TLS1.2 से कनेक्ट करने के लिए .NET को मैन्युअल रूप से कॉन्फ़िगर करने के लिए एप्लिकेशन कोड जोड़ें। (रोनाल्ड रामोस जवाब देखें )

@felickz को शानदार प्रतिक्रिया मिली। क्या विंडोज़ फोन 8 के लिए WebRequestHandler लाइब्रेरी के बराबर कोई है?
बिलट्रॉन

WP / Win8 के लिए @Billatron विभिन्न पुस्तकालय .. देखें
felickz

6
स्व-हस्ताक्षरित सेर्ट्स को विकसित या निपटाते समय आप निम्नलिखित के साथ अविश्वसनीय प्रमाणित त्रुटियों को अनदेखा कर सकते हैं: ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
डेवलपर

6
क्या है GetMyX509Certificate?
फंदी सुसंतो

6
@developer सिर्फ यह उम्मीद करता है कि कोड आपके प्रोडक्शन बिल्ड में स्लिप न हो :)
felickz

15

आपके कोड को इस तरह से संशोधित किया जाना चाहिए:

httpClient.BaseAddress = new Uri("https://foobar.com/");

आपको बस https:यूआरआई योजना का उपयोग करना होगा । सुरक्षित HTTP कनेक्शन के बारे में MSDN पर यहाँ एक उपयोगी पृष्ठ है । वास्तव में:

Https: URI योजना का उपयोग करें

HTTP प्रोटोकॉल दो URI योजनाओं को परिभाषित करता है:

http: अनएन्क्रिप्टेड कनेक्शन के लिए उपयोग किया जाता है।

https: सुरक्षित कनेक्शन के लिए उपयोग किया जाता है जिसे एन्क्रिप्ट किया जाना चाहिए। यह विकल्प यह सत्यापित करने के लिए डिजिटल प्रमाणपत्र और प्रमाणपत्र प्राधिकारी का भी उपयोग करता है कि सर्वर वह है जो यह होने का दावा करता है।

इसके अलावा, विचार करें कि HTTPS कनेक्शन एक SSL प्रमाणपत्र का उपयोग करते हैं। सुनिश्चित करें कि आपके सुरक्षित कनेक्शन में यह प्रमाणपत्र है अन्यथा अनुरोध विफल हो जाएंगे।

संपादित करें:

Http कॉल करने के लिए उपरोक्त कोड ठीक काम करता है। लेकिन जब मैं इस योजना को https में बदल देता हूं तो यह काम नहीं करता है, मुझे त्रुटि पोस्ट करने दें।

इसका क्या मतलब है काम नहीं करता है? अनुरोध विफल? एक अपवाद फेंका गया है? अपना प्रश्न स्पष्ट करें।

यदि अनुरोध विफल हो जाते हैं, तो समस्या एसएसएल प्रमाणपत्र होनी चाहिए।

समस्या को ठीक करने के लिए, आप वर्ग HttpWebRequestऔर फिर उसकी संपत्ति का उपयोग कर सकते हैं ClientCertificate। इसके अलावा, आप पा सकते हैं यहाँ कैसे प्रमाण पत्र का उपयोग कर एक HTTPS अनुरोध बनाने के बारे में एक उपयोगी नमूना।

एक उदाहरण निम्नलिखित है (जैसा कि MSDN पृष्ठ में पहले दिखाया गया है):

//You must change the path to point to your .cer file location. 
X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\\mycert.cer");
// Handle any certificate errors on the certificate from the server.
ServicePointManager.CertificatePolicy = new CertPolicy();
// You must change the URL to point to your Web server.
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://YourServer/sample.asp");
Request.ClientCertificates.Add(Cert);
Request.UserAgent = "Client Cert Sample";
Request.Method = "GET";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();

अनुरोध के साथ प्रमाण-पत्र भेजने में मुश्किल है। उसको कैसे करे?
अभिजीत

"C: \\ mycert.cer" कहाँ प्राप्त करें? Mycert.cer फ़ाइल कैसे जनरेट करें?
मसिबू

@masiboo मैंने HTTPS कॉल करने के तरीके के बारे में उत्तर लिखे। * .Cer फ़ाइल बनाने के तरीके के बारे में Google से पूछें और आपको स्वयं ही उत्तर मिल जाएगा।
अल्बर्टो सोलानो

9

कनेक्ट होने पर httpsमुझे यह त्रुटि भी मिली, मैं इस लाइन को पहले जोड़ता हूं HttpClient httpClient = new HttpClient();और सफलतापूर्वक कनेक्ट करता हूं :

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

मुझे यह उत्तर और एक अन्य समान अन्वेषक से पता है और टिप्पणी का उल्लेख है:

यह विकास में एक हैक उपयोगी है, इसलिए इसके चारों ओर #if DEBUG #endif स्टेटमेंट डालना कम से कम आपको यह सुरक्षित बनाने के लिए करना चाहिए और उत्पादन में इस समाप्ति को रोकना चाहिए

इसके अलावा, मैंने किसी अन्य उत्तर में विधि का उपयोग करने की कोशिश नहीं की है जो प्रमाण पत्र का उपयोग करता है new X509Certificate()या new X509Certificate2()बनाने के लिए है, मुझे यकीन नहीं है कि बस द्वारा new()काम करेगा या नहीं।

संपादित करें: कुछ संदर्भ:

IIS 7 में एक स्व-हस्ताक्षरित सर्वर प्रमाणपत्र बनाएँ

IIS 7 में SSL प्रमाणपत्र आयात और निर्यात करें

.Pfx को .cer में बदलें

ServerCertificateValidationCallback का उपयोग करने के लिए सर्वोत्तम अभ्यास

मुझे लगता है कि थम्बप्रिंट का मूल्य इसके बराबर है x509certificate.GetCertHashString():

प्रमाण पत्र की थम्बप्रिंट प्राप्त करें


6

मुझे GitHub से कनेक्ट करते समय एक ही समस्या थी, जिसके लिए एक उपयोगकर्ता एजेंट की आवश्यकता होती है। इस प्रकार यह प्रमाण पत्र बनाने के बजाय इसे प्रदान करने के लिए पर्याप्त है

var client = new HttpClient();

client.BaseAddress = new Uri("https://api.github.com");
client.DefaultRequestHeaders.Add(
    "Authorization",
    "token 123456789307d8c1d138ddb0848ede028ed30567");
client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add(
    "User-Agent",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");

2
आपको उस टोकन को रद्द करना चाहिए जिसे आप इंटरनेट के साथ साझा कर रहे हैं, मुझे लगता है कि GitHub ने स्वचालित रूप से ऐसा किया होगा।
अमियास

21
क्या आपको लगता है कि वास्तव में मेरा टोकन शुरू होता है 123456789??
कार्लो वी। डांगो

5

के स्तर पर एक गैर-वैश्विक सेटिंग है HttpClientHandler:

var handler = new HttpClientHandler()
{
    SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
};

var client = new HttpClient(handler);

इस प्रकार एक नवीनतम टीएलएस संस्करण को सक्षम करता है।

ध्यान दें, कि डिफ़ॉल्ट मूल्य SslProtocols.Defaultवास्तव में SslProtocols.Ssl3 | SslProtocols.Tls(.Net Core 2.1 और .Net फ्रेमवर्क 4.7.1 के लिए जाँच की गई है)।


जवाब के लिए धन्यवाद। थोड़ा ध्यान दें: इस दस्तावेज़ के अनुसार: docs.microsoft.com/en-us/dotnet/api/… यह कम से कम फ्रेमवर्क 4.7.1 की आवश्यकता है।
GELR

@ जीईएलआर हां, आप सही कह रहे हैं। उपरोक्त कोड .Net 4.6.1 में रन-टाइम त्रुटि देता है। जवाब तय किया।
स्टॉप-क्रेन

.NET फ्रेमवर्क के पिछले संस्करणों में, यह संपत्ति निजी है
JotaBe

नेट कोर 3.1 पर यह सब मेरे लिए काम किया है। वैश्विक System.Net.ServicePointManager.SecurityProtocol = xxx को सेट करना - एक पैकेट ट्रेस में बिल्कुल शून्य प्रभाव था।
रोवन स्मिथ

3

यूआरआई में एचटीटीपीएस को निर्दिष्ट करने के लिए केवल चाल चलनी चाहिए।

httpClient.BaseAddress = new Uri("https://foobar.com/");

यदि अनुरोध HTTP के साथ काम करता है, लेकिन HTTPS के साथ विफल रहता है, तो यह निश्चित रूप से एक प्रमाणपत्र समस्या है । सुनिश्चित करें कि कॉलर प्रमाणपत्र जारीकर्ता पर भरोसा करता है और प्रमाणपत्र समाप्त नहीं हुआ है। यह देखने का एक त्वरित और आसान तरीका है कि ब्राउज़र में क्वेरी बनाने का प्रयास करें।

आप सर्वर पर जांच करना चाहते हैं (यदि यह आपका है और / या यदि आप कर सकते हैं) कि यह एचटीटीपीएस अनुरोधों को ठीक से पूरा करने के लिए सेट है।


: मेरे पास एक समान मुद्दा है: मैंने ब्राउज़र में क्वेरी की है और प्रमाण पत्र वैध है (कॉल पास से गुजरता है, सेवा स्तर के रूप में अधिकृत है और सभी एक आकर्षण की तरह काम करता है) लेकिन प्रोग्रामेटिक रूप से काम नहीं करता है। और क्या हो सकता है? अगर मैं वेब अनुप्रयोग से ब्राउज़र "मैन्युअल रूप से कॉलिंग सेवा" से बिल्कुल उसी सर्टिफिकेट का उपयोग करता हूं, जो प्रोग्राम को क्रमिक रूप से कह रहा है?
कार्लोस

2

मुझे भी त्रुटि हो रही थी:

अंतर्निहित कनेक्शन बंद कर दिया गया था: एसएसएल / टीएलएस सुरक्षित चैनल के लिए विश्वास संबंध स्थापित नहीं कर सका।

... एक Xamarin फॉर्म के साथ एंड्रॉइड -एप्लिकेशन को एपीआई प्रदाता से संसाधनों का अनुरोध करने का प्रयास करने वाला आवेदन, जिसमें टीएलएस 1.3 की आवश्यकता होती है

समाधान XAMarin "प्रबंधित" (.NET) http क्लाइंट (जो कि TAMS 1.3 को Xamarin Forms v2.5 के रूप में समर्थन नहीं करता है) को स्वैप करने के लिए प्रोजेक्ट कॉन्फ़िगरेशन को अद्यतन करने के लिए था, और इसके बजाय Android मूल क्लाइंट का उपयोग करें।

यह दृश्य स्टूडियो में एक सरल प्रोजेक्ट टॉगल है। नीचे स्क्रीनशॉट देखें

  • परियोजना के गुण
  • Android विकल्प
  • उन्नत
  • सामग्री सूचीबद्ध करें
  • "HttpClient कार्यान्वयन" को "Android" में बदलें
  • SSL / TLS कार्यान्वयन को "मूल TLS 1.2+" में बदलें

यहां छवि विवरण दर्ज करें


1

अपनी कक्षा में निम्न घोषणाएँ जोड़ें:

public const SslProtocols _Tls12 = (SslProtocols)0x00000C00;
public const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12;

उपरांत:

var client = new HttpClient();

तथा:

ServicePointManager.SecurityProtocol = Tls12;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 /*| SecurityProtocolType.Tls */| Tls12;

प्रसन्न? :)


1

मेरे पास यह मुद्दा था और मेरे मामले में समाधान मूर्खतापूर्ण सरल था: प्रशासक अधिकारों के साथ विजुअल स्टूडियो खोलें। मैंने उपरोक्त सभी समाधानों की कोशिश की और यह तब तक काम नहीं किया जब तक मैंने ऐसा नहीं किया। आशा है कि यह किसी को कुछ कीमती समय बचाता है।


चूँकि आप साइट पर नए हैं, आप यह नहीं जान सकते कि यदि किसी उत्तर के बगल में हरे रंग की जाँच है, तो इसका मतलब है कि यह ओपी द्वारा उसकी समस्या के लिए सही समाधान के रूप में स्वीकार किया गया था। जब तक आप एक बेहतर, अधिक पूर्ण उत्तर नहीं दे सकते, तब तक शायद एक और उत्तर प्रस्तुत न करना सबसे अच्छा है, विशेषकर ऐसे पुराने प्रश्न पर।
सैम डब्ल्यू

4
खैर, मेरे पास भी यह मुद्दा था, और हरे रंग की जाँच की गई उत्तर ने बिल्कुल मदद नहीं की। सोचा कि मैं एक वैकल्पिक समाधान देता हूं जिससे मुझे मदद मिली, लेकिन हे, मैं अगली बार ऐसा नहीं करूंगा। माइनस पॉइंट्स के लिए धन्यवाद;) का दिन बहुत अच्छा हो।
लूसियन सतमरियन

0

आप ModernHttpClient Nuget पैकेज का उपयोग करने का प्रयास कर सकते हैं : पैकेज डाउनलोड करने के बाद, आप इसे इस तरह से लागू कर सकते हैं:

 var handler = new ModernHttpClient.NativeMessageHandler()
 {
     UseProxy = true,
 };


 handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
 handler.PreAuthenticate = true;
 HttpClient client = new HttpClient(handler);

दुर्भाग्य से, इससे मुझे काम नहीं मिला। समाधान के लिए TLS 1.3 को सक्षम करना था ताकि xamarin से http क्लाइंट को Android- मूल http क्लाइंट पर स्विच किया जा सके। नीचे मेरा जवाब देखें।
MSC

0

मैं felickz से सहमत हूं, लेकिन मैं c # में उपयोग को स्पष्ट करने के लिए एक उदाहरण भी जोड़ना चाहता हूं। मैं निम्नानुसार विंडोज़ सेवा में एसएसएल का उपयोग करता हूं।

    var certificatePath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");
    gateway = new GatewayService();
    gateway.PreAuthenticate = true;


    X509Certificate2 cert = new X509Certificate2(certificatePath + @"\Attached\my_certificate.pfx","certificate_password");
    gateway.ClientCertificates.Add(cert);

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    gateway.UserAgent = Guid.NewGuid().ToString();
    gateway.Timeout = int.MaxValue;

अगर मैं इसे वेब एप्लिकेशन में उपयोग करने जा रहा हूं, तो मैं इस तरह प्रॉक्सी पक्ष पर कार्यान्वयन को बदल रहा हूं:

public partial class GatewayService : System.Web.Services.Protocols.SoapHttpClientProtocol // to => Microsoft.Web.Services2.WebServicesClientProtocol

-4

त्रुटि के लिए:

अंतर्निहित कनेक्शन बंद कर दिया गया था: एसएसएल / टीएलएस सुरक्षित चैनल के लिए विश्वास संबंध स्थापित नहीं कर सका।

मुझे लगता है कि आपको निम्नलिखित कोड के साथ बिना शर्त प्रमाणपत्र स्वीकार करने की आवश्यकता है

ServicePointManager.ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

जैसा कि विपक्षी ने अपने जवाब में लिखा था। NET क्लाइंट ssl Web API से कनेक्ट हो रहा है


4
यह प्रमाणित सत्यापन को दरकिनार कर रहा है। उत्पादन में ऐसा कभी न करें।
जॉन कोर्न्स

वैसे @JohnKorsnes, अगर अभिजीत कुछ सार्वजनिक WebAPI सर्वर तक पहुंच रहा है, तो मुझे नहीं लगता कि वह इसके लिए ज्यादा कुछ कर सकता है। यह मेरा मामला था।
नेमेनजा सिमियोविच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.