2011-10-12 21 views
13

मैं एक वेब साइट है कि एक और वेब साइट पर एक MVC नियंत्रक कार्रवाई कॉल करने के लिए कोशिश कर रहा है है। ये साइटें एडी एफएस 2.0 में निर्भर पार्टी ट्रस्ट के रूप में दोनों सेट हैं। दो साइटों के बीच ब्राउज़र विंडो में पृष्ठों को खोलते समय सबकुछ प्रमाणित करता है और ठीक काम करता है। हालांकि, jQuery AJAX विधि का उपयोग कर जावास्क्रिप्ट से नियंत्रक कार्रवाई को कॉल करने का प्रयास करते समय यह हमेशा विफल रहता है। यहाँ मैं क्या कर रहा हूँ की एक कोड का टुकड़ा ...ई FS 2.0 प्रमाणीकरण और AJAX

$.ajax({ 
    url: "relyingPartySite/Controller/Action", 
    data: { foobar }, 
    dataType: "json", 
    type: "POST", 
    async: false, 
    cache: false, 
    success: function (data) { 
    // do something here 
    }, 
    error: function (data, status) { 
    alert(status); 
    } 
}); 

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

+1

यदि HTML को AJAX कॉल द्वारा वापस किया जा रहा है, तो स्पष्ट रूप से आप इसे जेसन पार्सर से पार्स नहीं करना चाहते हैं। डेटा बदलें "एचटीएमएल" टाइप करें, और एचटीएमएल का एक उदाहरण पोस्ट करें, इसलिए मैं आपको दिखा सकता हूं कि एक हैंडलर कैसे लिखना है जो लौटा हुआ फॉर्म जमा करेगा। – ironchefpython

+0

मुद्दा यह है कि मैं JSON वापस प्राप्त करना चाहता हूं। एडी एफएस एक नए एचटीएमएल फॉर्म के साथ रीडायरेक्ट करता है जो इसे हैंडशेक करने के लिए पोस्ट करना चाहता है। यह एक ब्राउज़र विंडो के भीतर ठीक काम करता है लेकिन यहां नहीं। एक बार हैंडशेक होने पर AJAX अनुरोध के साथ कोई रीडायरेक्ट नहीं होता है और मैं JSON वापस आ जाता हूं। मैं आईएफआरएएम में एचटीएमएल पेज पोस्ट को संभालने के लिए अभी एक कामकाज के साथ आया हूं लेकिन यह आदर्श नहीं है। –

+0

मैं समझता हूं कि आप जेएसओएन वापस लेना चाहते हैं, लेकिन आप JSON वापस नहीं जा रहे हैं। _However_, यदि आप लौटाए गए डेटा स्ट्रक्चर का इलाज करने में सक्षम होना चाहते हैं जैसे कि यह _were_ JSON है, तो HTML का एक उदाहरण पोस्ट करें, और मैं आपको दिखाऊंगा कि एक हैंडलर कैसे लिखना है जो ** के बिना लौटा फॉर्म सबमिट करेगा ** एक IFRAME का उपयोग कर। – ironchefpython

उत्तर

0

सबसे पहले आप कहते हैं कि तुम के लिए एक ajax कॉल एक और वेबसाइट बनाने के लिए कोशिश कर रहे हैं, अपने कॉल वेब ब्राउज़र के same origin policy के अनुरूप है? यह तो आप अपने सर्वर से प्रतिक्रिया के रूप में एचटीएमएल उम्मीद कर रहे हैं होता है, तो dataType: "html" को ajax कॉल के datatype बदलने के लिए, तो अपने डोम में प्रपत्र सम्मिलित करें।

0

शायद this serie के 2 पहली पोस्ट आप में मदद मिलेगी। वे एडीएफएस और AJAX अनुरोधों पर विचार करते हैं

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

+0

कुकीज संचरित हो जाता है कि हैंडशेक होता है। यह समस्या है कि हैंडशेक AJAX अनुरोध पर होने का प्रयास कर रहा है यदि यह पहली बार है। –

0

आप अपने Fiddler कि केवल एचटीएमएल लौटा रहा है फिर HTML के लिए अपने डेटा प्रकार बदलने में देख सकते हैं या यदि वह केवल एक स्क्रिप्ट कोड तो आप स्क्रिप्ट का उपयोग कर सकते हैं डेटाप्रकार

"xml": Treat the response as an XML document that can be processed via jQuery. 

"html": Treat the response as HTML (plain text); included script tags are evaluated. 

"script": Evaluates the response as JavaScript and evaluates it. 

"json": Evaluates the response as JSON and sends a JavaScript Object to the success callback. 

का केवल इस प्रकार के कर सकते हैं।

-1

आप json.php की तरह एक फ़ाइल anyname बनाना होगा और relayparty वेबसाइट के लिए कनेक्शन डाल इस करना चाहिए काम करता है $.ajax({ url: "json.php", data: { foobar }, dataType: "json", type: "POST", async: false, cache: false, success: function (data) { // do something here }, error: function (data, status) { alert(status); } });

1

आप लिंक के साथ HTML आप WSFederationAuthenticationModule पर AuthorizationFailed संभाल कर सकते हैं प्राप्त करने के लिए नहीं करना चाहते हैं और false करने के लिए RedirectToIdentityProvider सेट अजाक्स केवल कॉल पर।

उदाहरण के लिए

:

FederatedAuthentication.WSFederationAuthenticationModule.AuthorizationFailed += (sender, e) => 
{ 
    if (Context.Request.RequestContext.HttpContext.Request.IsAjaxRequest()) 
    { 
     e.RedirectToIdentityProvider = false; 
    } 
}; 

यह Authorize विशेषता के साथ स्थिति कोड 401 वापस आ जाएगी और अगर आप कुछ अलग करना चाहते हैं, तो आप खुद Authorize विशेषता को लागू करने और अजाक्स अनुरोध पर विशेष कोड लिख सकते हैं।

+0

जेएस में 403 को संभालें और सुरक्षित क्षेत्र के अंदर एक एचटीएमएल पेज के साथ एक आईफ्रेम लोड करें, सभी क्रैपी एडीएफ रीडायरेक्ट होंगे और आपको अपनी कुकीज़ मिल जाएगी ... फिर आप कॉल –

+0

कॉल कर सकते हैं क्षमा करें, 401 नहीं 403 –

+0

यह 'सिद्धांत में)' Global_asax.cs' की 'Application_Start()' विधि में ठीक काम करना चाहिए - लेकिन नहीं। हालांकि, यह 'Application_BeginRequest() 'में ठीक काम करता है। –

3

आपके पास दो विकल्प हैं। अधिक जानकारी here

पहला एंट्री एप्लिकेशन (एक HTML आधारित है) और आपके एपीआई समाधान के बीच सत्र कुकी साझा करना है। आप एक ही WIF कुकी का उपयोग करने के लिए दोनों अनुप्रयोगों को कॉन्फ़िगर करते हैं। यह केवल तभी काम करता है जब दोनों अनुप्रयोग एक ही रूट डोमेन पर हों। उपर्युक्त पोस्ट या यह stackoverflow question देखें।

दूसरा विकल्प AJAX अनुरोधों के लिए passiveRedirect को अक्षम करना है (Gutek's answer के रूप में)। यह 401 का एक http स्टेटस कोड लौटाएगा जिसे आप जावास्क्रिप्ट में संभाल सकते हैं। जब आप 401 का पता लगाते हैं, तो आप एक आईफ्रेम में एक डमी पेज (या एक "प्रमाणीकरण" संवाद लोड करते हैं जो एक लॉगिन संवाद के रूप में दोगुना हो सकता है)। जब आईफ्रेम ने आपको पूरा कर लिया है तो फिर कॉल का प्रयास करें। इस बार सत्र कुकी कॉल पर उपस्थित होगी और इसे सफल होना चाहिए।

//Requires Jquery 1.9+ 
var webAPIHtmlPage = "http://webapi.somedomain/preauth.html" 

function authenticate() { 
    return $.Deferred(function (d) { 
     //Potentially could make this into a little popup layer 
     //that shows we are authenticating, and allows for re-authentication if needed 
     var iFrame = $("<iframe></iframe>"); 
     iFrame.hide(); 
     iFrame.appendTo("body"); 
     iFrame.attr('src', webAPIHtmlPage); 
     iFrame.load(function() { 
      iFrame.remove(); 
      d.resolve(); 
     }); 
    }); 
}; 

function makeCall() { 
    return $.getJSON(uri) 
       .then(function(data) { 
         return $.Deferred(function(d) { d.resolve(data); }); 
        }, 
        function(error) { 
         if (error.status == 401) { 
          //Authenticating, 
          //TODO:should add a check to prevnet infinite loop 
          return authenticate().then(function() { 
           //Making the call again 
           return makeCall(); 

          }); 
         } else { 
          return $.Deferred(function(d) { 
           d.reject(error); 
          }); 
         } 
       }); 
} 
+0

आईफ्रेम समाधान केवल आईफ्रेम को हटाकर मेरे लिए काम नहीं करता है, लेकिन इसकी सामग्री iFrame.load (फ़ंक्शन() { var content = iFrame.contents(); हल करें(); }); – GitteTitter

+0

दूसरा विकल्प मेरे लिए काम कर रहा है अगर मैं अजाक्स का उपयोग कर प्राप्त करता हूं। लेकिन अगर मैं कोई पोस्ट करता हूं तो ब्राउज़र अनुरोध के साथ iFrame द्वारा लोड की गई कुकी नहीं भेज रहा है। कोई विचार क्यों? – NLV

0

परियोजना जो मैं वर्तमान के साथ काम में, हम clientside पर SAML टोकन समाप्ति और ajax कॉल के साथ मुद्दों के कारण के साथ एक ही मुद्दा था। हमारे विशेष मामले में हमें पहले 401 का सामना करने के बाद सभी सफल अनुरोधों की आवश्यकता थी और सफल प्रमाणीकरण के बाद उन सभी को नाराज हो सकता था। प्रमाणीकरण एडम मिल्स द्वारा सुझाए गए आईफ्रेम समाधान का उपयोग करता है, लेकिन उपयोगकर्ता प्रमाण-पत्रों को दर्ज करने की आवश्यकता होने पर थोड़ा और आगे जाता है, जो उपयोगकर्ता को बाहरी दृश्य पर लॉगिन करने के लिए सूचित करने वाले संवाद को प्रदर्शित करके किया जाता है (क्योंकि एडीएफएस लॉगिन प्रदर्शित करने की अनुमति नहीं देता है iframe में पृष्ठ कम से कम डिफ़ॉल्ट कॉन्फ़िगरेशन नहीं है) जिसके दौरान प्रतीक्षा अनुरोध समाप्त होने का इंतजार कर रहा है लेकिन उपयोगकर्ता को बाहरी पृष्ठ से लॉगिन करने की आवश्यकता है। यदि अनुरोध रद्द करना चुनता है तो उन अनुरोधों को प्रतीक्षा अनुरोध भी खारिज कर दिया जा सकता है और उन मामलों में प्रत्येक अनुरोध के लिए jquery त्रुटि बुलाई जाएगी।

यहां उदाहरण के कोड के साथ एक सार के लिए एक लिंक है:

https://gist.github.com/kaveh82/bb0d8e4a446496a6c05a

नोट मेरी कोड सभी ajax अनुरोध को संभालने के लिए jQuery के उपयोग पर आधारित है। यदि आपका AJAX अनुरोध वेनिला जावास्क्रिप्ट, अन्य पुस्तकालयों या ढांचे द्वारा संभाला जा रहा है तो आप शायद इस उदाहरण में कुछ प्रेरणा पा सकते हैं। Jquery ui का उपयोग केवल संवाद की वजह से है और कोड के एक छोटे से हिस्से के लिए खड़ा है जिसे आसानी से बदला जा सकता है।