32

के साथ ASP.NET वेब एपीआई सेवा को प्रमाणित करने में असमर्थ मेरे पास एक एएसपी.NET वेब एपीआई सेवा है जो विंडोज प्रमाणीकरण सक्षम वेब सर्वर पर चलती है।HttpClient

मैं एक ग्राहक MVC4 पर बनाया गया साइट है कि सेवा से डेटा खींचने के लिए HttpClient का उपयोग करता है एक ही वेब सर्वर पर एक अलग साइट में चलाता है। यह क्लाइंट साइट पहचान प्रतिरूपण सक्षम के साथ चलता है और विंडोज प्रमाणीकरण का भी उपयोग करता है।

वेब सर्वर आईआईएस 7.5 के साथ विंडोज सर्वर 2008 आर 2 है।

चुनौती मैं कर रहा हूँ HttpClient हो रही अपनी प्रमाणीकरण की प्रक्रिया के हिस्से के रूप में वर्तमान खिड़कियों उपयोगकर्ता पारित करने के लिए है। मैं इस तरह से HttpClient कॉन्फ़िगर किया है:

var clientHandler = new HttpClientHandler(); 
clientHandler.UseDefaultCredentials = true; 
clientHandler.PreAuthenticate = true; 
clientHandler.ClientCertificateOptions = ClientCertificateOption.Automatic; 
var httpClient = new HttpClient(clientHandler); 

मेरे समझ के साथ कि पहचान प्रतिरूपण सक्षम के साथ साइट चल रहा है और उसके बाद इस तरह से ग्राहक के निर्माण के प्रतिरूपित पहचान का उपयोग कर ग्राहक सेवा पर प्रमाणीकरण में परिणाम चाहिए वर्तमान में उपयोगकर्ता में लॉग इन है।

यह नहीं हो रहा है। वास्तव में, ग्राहक बिल्कुल प्रमाणीकरण प्रतीत नहीं होता है।

सेवा विंडोज प्रमाणीकरण का उपयोग करने के लिए कॉन्फ़िगर किया गया है और यह पूरी तरह से काम करता प्रतीत होता है। मैं अपने वेब ब्राउजर में http://server/api/shippers पर जा सकता हूं और विंडोज प्रमाणीकरण के लिए संकेत दिया जा सकता है, एक बार दर्ज होने पर मुझे अनुरोध किया गया डेटा प्राप्त होता है।

आईआईएस लॉग में मैं एपीआई अनुरोधों को प्रमाणीकरण के साथ प्राप्त नहीं कर रहा हूं और 401 चुनौती प्रतिक्रिया प्राप्त कर रहा हूं।

इस पर प्रलेखन स्पैस लगता है।

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

धन्यवाद, क्रेग

उत्तर

31

मैं के स्रोत कोड की जांच की है HttpClientHandler (नवीनतम संस्करण मैं पर मेरे हाथ पाने के लिए कर रहा था) और इस SendAsync विधि में क्या पाया जा सकता है है:

// BeginGetResponse/BeginGetRequestStream have a lot of setup work to do before becoming async 
// (proxy, dns, connection pooling, etc). Run these on a separate thread. 
// Do not provide a cancellation token; if this helper task could be canceled before starting then 
// nobody would complete the tcs. 
Task.Factory.StartNew(startRequest, state); 

अब यदि आप अपने कोड में सुरक्षा कॉन्टेक्स्ट का मूल्य जांचते हैं। IWindowsIdentityFlowSuppressed() आप शायद अधिकतर सच हो जाएंगे। नतीजतन StartRequest विधि को एएसपीनेट प्रक्रिया के प्रमाण पत्र के साथ नए धागे में निष्पादित किया जाता है (प्रतिरूपित उपयोगकर्ता के प्रमाण पत्र नहीं)।

इसमें से दो संभावित तरीके हैं।

<legacyImpersonationPolicy enabled="false"/> 
<alwaysFlowImpersonationPolicy enabled="true"/> 

आप aspnet_config.config बदल नहीं सकते तो आप करना होगा: तुम अपने सर्वर aspnet_config.config की पहुंच है, तो आपको निम्न सेटिंग्स (स्थापित करने web.config में उन पर कोई असर नहीं रहा है) स्थापित करना चाहिए इस परिदृश्य का समर्थन करने के लिए अपना खुद का HttpClientHandler बनाने के लिए।

अद्यतन FQDN

मुद्दा आप यहाँ मारा है के उपयोग के बारे कि "प्रतिबिंब हमलों" के खिलाफ की रक्षा करने के लिए डिज़ाइन किया गया है Windows में एक विशेषता है। इसके आस-पास काम करने के लिए आपको उस सर्वर पर श्वेतसूची की आवश्यकता है जिसे आप सर्वर तक पहुंचने का प्रयास कर रहे हैं।नीचे दिए गए चरणों का पालन करें:

  1. जाओ शुरू करने के लिए -> भागो -> regedit
  2. जानें HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 रजिस्ट्री कुंजी।
  3. उस पर राइट-क्लिक करें, नया और फिर मल्टी-स्ट्रिंग मान चुनें।
  4. टाइप BackConnectionHostNames ( दर्ज करें)।
  5. केवल बनाए गए मान पर राइट-क्लिक करें और चुनें संशोधित करें।
  6. साइट बॉक्स के लिए होस्ट नाम (ओं) को स्थानीय बॉक्स पर मूल्य बॉक्स में रखें और ठीक पर क्लिक करें (प्रत्येक होस्ट नाम/FQDN को अपनी लाइन पर होना आवश्यक है, कोई वाइल्डकार्ड नहीं है, नाम सटीक मिलान होना चाहिए)।
  7. सब कुछ सहेजें और मशीन

आप इस मुद्दे के बारे में here पूर्ण KB लेख पढ़ सकते हैं पुनरारंभ करें।

+0

अच्छी तरह से देखा गया .. .. – Aliostad

+0

मैं आगे बढ़ गया और इन मानों को व्यवहार में कोई बदलाव नहीं किया। अजीब चीज यह है कि मैं क्लाइंट को सर्वर पर मारने और 401 प्रतिक्रिया प्राप्त करने वाला क्लाइंट देख सकता हूं। HttpClient बस किसी भी प्रमाणीकरण जानकारी नहीं भेज रहा है और केवल 401 और quits प्राप्त करता है। कोई अतिरिक्त विचार? –

+0

इसके अतिरिक्त, मैंने उस एप्लिकेशन पूल की पहचान बदल दी है जो क्लाइंट विंडोज़ खाते में चल रहा है जिसमें सेवा तक पहुंच है। इसके परिणामस्वरूप कोई बदलाव नहीं हुआ। मैं इस पर खो गया हूँ? –

8

मुझे भी यही समस्या थी। @tpeczek द्वारा किए गए शोध के लिए धन्यवाद, मैंने निम्नलिखित समाधान विकसित किए: HttpClient (जो थ्रेड्स बनाता है और अनुरोध async भेजता है) का उपयोग करने के बजाय, मैंने वेब क्लाइंट क्लास का उपयोग किया जो एक ही थ्रेड पर अनुरोध जारी करता है। ऐसा करने से मुझे किसी अन्य एएसपी.NET एप्लिकेशन से वेबएपीआई को उपयोगकर्ता की पहचान पास करने में मदद मिलती है।

स्पष्ट नकारात्मकता यह है कि यह async काम नहीं करेगा।

var wi = (WindowsIdentity)HttpContext.User.Identity; 

var wic = wi.Impersonate(); 
try 
{ 
    var data = JsonConvert.SerializeObject(new 
    { 
     Property1 = 1, 
     Property2 = "blah" 
    }); 

    using (var client = new WebClient { UseDefaultCredentials = true }) 
    { 
     client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8"); 
     client.UploadData("http://url/api/controller", "POST", Encoding.UTF8.GetBytes(data)); 
    } 
} 
catch (Exception exc) 
{ 
    // handle exception 
} 
finally 
{ 
    wic.Undo(); 
} 

नोट: Newtonsoft.Json, जो एक ही JSON serializer वेबएपीआई का उपयोग करता है: NuGet पैकेज की आवश्यकता है।

+0

धन्यवाद, यह वही है जो मुझे चाहिए। –

+0

वाह। WindowsImpersonationContext। आपने दिन और मेरी सैनिटी बचाई। धन्यवाद। – granadaCoder

+0

क्या आपने async समकक्षों का उपयोग करने की कोशिश की है जैसे अपलोडडेटाएसिंक :-) –

0

कारण यह काम नहीं कर रहा है क्योंकि आपको डबल हॉप प्रमाणीकरण की आवश्यकता है।

पहली हॉप वेब सर्वर है, काम करने के लिए विंडोज प्रमाणीकरण के साथ प्रतिरूपण प्राप्त करने में कोई समस्या नहीं है। लेकिन जब आप किसी अन्य सर्वर पर प्रमाणीकृत करने के लिए HttpClient या WebClient का उपयोग करते हैं, तो वेब सर्वर को उस खाते पर चलने की आवश्यकता होती है जिसके लिए आवश्यक प्रतिनिधिमंडल करने की अनुमति होती है।
http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx

"Setspn" का उपयोग फिक्स आदेश:

अधिक जानकारी के लिए निम्न देखें
http://www.phishthis.com/2009/10/24/how-to-configure-ad-sql-and-iis-for-two-hop-kerberos-authentication-2/ (। आप इन कार्यों का प्रदर्शन करने के लिए पर्याप्त अधिकारों का उपयोग की आवश्यकता होगी)

बस पर विचार क्या ऐसा होगा अगर किसी सर्वर को आपके क्रेडेंशियल्स को आगे बढ़ने की अनुमति दी गई थी ... इस सुरक्षा समस्या से बचने के लिए, डोमेन नियंत्रक को यह पता होना चाहिए कि प्रतिनिधिमंडल को कौन से खातों की अनुमति है।

0

मूल (प्रमाणीकृत) प्रयोक्ता का रूप धारण करने के लिए, Web.config फ़ाइल में निम्न कॉन्फ़िगरेशन का उपयोग करें:

<authentication mode="Windows" /> 
<identity impersonate="true" /> 
इस कॉन्फ़िगरेशन के साथ

, ASP.NET हमेशा प्रमाणित उपयोगकर्ता को प्रतिरूपित करता है, और सभी संसाधन का उपयोग किया जाता है प्रमाणीकृत उपयोगकर्ता के सुरक्षा संदर्भ का उपयोग कर।