.NET में सत्यापन के साथ OAuth


103

मैं एक .NET-आधारित क्लाइंट ऐप (WPF में) बनाने की कोशिश कर रहा हूं - हालांकि उस समय के लिए मैं इसे एक कंसोल ऐप के रूप में कर रहा हूं) OAuth- सक्षम एप्लिकेशन, विशेष रूप से मेंडली ( http: // dev ) के साथ एकीकृत करने के लिए .mendeley.com ), जो स्पष्ट रूप से 3-पैर वाले OAuth का उपयोग करता है।

यह OAuth का उपयोग करने का मेरा पहला मौका है, और मुझे इसके साथ शुरुआत करने में बहुत कठिनाई हो रही है। मैंने कई .NET OAuth पुस्तकालयों या सहायकों को पाया है, लेकिन मुझे लगता है कि मुझे लगता है कि वे मेरी तुलना में अधिक जटिल हैं। मैं केवल इतना करना चाहता हूं कि मेंडली एपीआई के लिए अन्य अनुरोधों को जारी करने और प्रतिक्रियाएं प्राप्त करने में सक्षम हो!

अब तक, मैंने कोशिश की है:

पहला (DotNetOpenAuth) ऐसा लगता है कि यह संभव हो सकता है कि मुझे क्या ज़रूरत है अगर मैं घंटों और घंटों काम करने की कोशिश करूं। दूसरा और तीसरा, जैसा कि सबसे अच्छा मैं बता सकता हूं, वे सत्यापन कोड का समर्थन नहीं करते हैं जो मेंडली वापस भेज रहे हैं - हालांकि मैं इसके बारे में हो सकता है :)

मुझे Mendeley से एक उपभोक्ता कुंजी और रहस्य मिला है, और DotNetOpenAuth के साथ मैं Mendeley पृष्ठ के साथ एक ब्राउज़र प्राप्त करने में कामयाब रहा जो उपयोगकर्ता को आवेदन में प्रवेश करने के लिए एक सत्यापन कोड प्रदान करता है। हालाँकि, इस बिंदु पर मैं हार गया और समझदारी से काम नहीं ले सका कि आवेदन को वापस कैसे प्रदान किया जाए।

मैं यह मानने के लिए तैयार हूं कि मुझे इस बारे में कोई जानकारी नहीं है कि इसे कहां से शुरू करना है (हालांकि ऐसा लगता है कि यह काफी कठिन सीखने की अवस्था है) - अगर कोई मुझे सही दिशा में इंगित कर सकता है तो मैं इसकी सराहना करूंगा!

जवाबों:


182

मैं आपसे सहमत हुँ। .NET ऐप्स के लिए उपलब्ध ओपन-सोर्स OAuth सपोर्ट क्लासेस को समझना मुश्किल है, अत्यधिक जटिल (DotNetOpenAuth द्वारा कितने तरीके उजागर किए जाते हैं?), खराब तरीके से डिज़ाइन किए गए (उस Google से OAuthBase.cs मॉड्यूल में 10 स्ट्रिंग मापदंडों वाले तरीकों को देखें) आपके द्वारा दिया गया लिंक - इसमें कोई राज्य प्रबंधन नहीं है), या अन्यथा असंतोषजनक।

यह इस जटिल होने की जरूरत नहीं है।

मैं OAuth का विशेषज्ञ नहीं हूं, लेकिन मैंने OAuth क्लाइंट-साइड प्रबंधक वर्ग का उत्पादन किया है, जिसका मैं ट्विटर और ट्विटपिक के साथ सफलतापूर्वक उपयोग करता हूं। यह उपयोग करने के लिए अपेक्षाकृत सरल है। यह खुला स्रोत है और यहां उपलब्ध है: Oauth.cs

समीक्षा के लिए, OAuth 1.0a में ... थोड़े मजाकिया, एक विशेष नाम है और यह "मानक" जैसा दिखता है, लेकिन जहां तक ​​मुझे एकमात्र सेवा पता है कि "OAuth 1.0a" ट्विटर पर लागू होता है। मुझे लगता है कि यह पर्याप्त मानक है । ठीक है, वैसे भी OAuth 1.0a में, डेस्कटॉप ऐप्स के लिए काम करने का तरीका यह है:

  1. आप, एप्लिकेशन के डेवलपर, ऐप को पंजीकृत करते हैं और "उपभोक्ता कुंजी" और "उपभोक्ता रहस्य" प्राप्त करते हैं। Arstechnica पर, इस मॉडल का सबसे अच्छा विश्लेषण नहीं है कि यह मॉडल सबसे अच्छा क्यों नहीं है , लेकिन जैसा कि वे कहते हैं, यह वही है जो यह है

  2. आपका ऐप चलता है। पहली बार जब यह चलता है, तो उपयोगकर्ता को ट्विटर और उसकी बहन सेवाओं (जैसे TwitPic) के लिए oauth- प्रामाणिक REST अनुरोध करने के लिए स्पष्ट रूप से ऐप के लिए स्वीकृति प्रदान करने की आवश्यकता होती है। ऐसा करने के लिए आपको एक अनुमोदन प्रक्रिया से गुजरना होगा, जिसमें उपयोगकर्ता द्वारा स्पष्ट अनुमोदन शामिल होगा। यह केवल पहली बार होता है जब ऐप चलता है। ऐशे ही:

    • एक "अनुरोध टोकन" का अनुरोध करें। अका अस्थायी टोकन।
    • एक वेब पेज को पॉप करें, जो उस अनुरोध टोकन को क्वेरी परम के रूप में पास करता है। यह वेब पेज उपयोगकर्ता को यूआई प्रस्तुत करता है, यह पूछते हुए कि "क्या आप इस ऐप को एक्सेस देना चाहते हैं?"
    • उपयोगकर्ता ट्विटर वेब पेज पर लॉग इन करता है, और पहुँच को अस्वीकार या अस्वीकार करता है।
    • प्रतिक्रिया html पृष्ठ दिखाई देता है। यदि उपयोगकर्ता ने पहुंच प्रदान की है, तो 48-pt फ़ॉन्ट में एक पिन प्रदर्शित होता है
    • उपयोगकर्ता को अब विंडोज फॉर्म बॉक्स में उस पिन को काटने / पेस्ट करने की आवश्यकता है, और "अगला" या कुछ समान पर क्लिक करें।
    • डेस्कटॉप ऐप फिर "एक्सेस टोकन" के लिए एक ऑथ-ऑथेंटिकेटेड अनुरोध करता है। एक और अनुरोध।
    • डेस्कटॉप ऐप "एक्सेस टोकन" और "एक्सेस सीक्रेट" प्राप्त करता है।

अनुमोदन नृत्य के बाद, डेस्कटॉप ऐप उपयोगकर्ता की ओर से प्रमाणित अनुरोध करने के लिए उपयोगकर्ता-विशिष्ट "एक्सेस टोकन" और "एक्सेस सीक्रेट" (ऐप-विशिष्ट "उपभोक्ता कुंजी" और "उपभोक्ता रहस्य" के साथ) का उपयोग कर सकता है। ट्विटर को। ये समाप्त नहीं होते हैं, हालांकि यदि उपयोगकर्ता ऐप को डी-अधिकृत करता है, या यदि किसी कारण से ट्विटर आपके ऐप को डी-अधिकृत करता है, या यदि आप अपना एक्सेस टोकन और / या गुप्त खो देते हैं, तो आपको फिर से अनुमोदन नृत्य करने की आवश्यकता होगी ।


यदि आप चतुर नहीं हैं, तो UI प्रवाह दर्पण को बहु-चरण OAuth संदेश प्रवाह की तरह कर सकता है। एक बेहतर रास्ता है।

WebBrowser नियंत्रण का उपयोग करें, और डेस्कटॉप ऐप के भीतर अधिकृत वेब पेज खोलें। जब उपयोगकर्ता "अनुमति" पर क्लिक करता है, तो उस WebBrowser नियंत्रण से प्रतिक्रिया पाठ को पकड़ो, स्वचालित रूप से पिन निकालें, फिर पहुंच टोकन प्राप्त करें। आप 5 या 6 HTTP अनुरोध भेजते हैं, लेकिन उपयोगकर्ता को केवल एक ही अनुमति / इनकार संवाद देखने की आवश्यकता होती है। सरल।

ऐशे ही:
वैकल्पिक शब्द


यदि आपने UI को सॉर्ट कर लिया है, तो एकमात्र चुनौती जो ऑउथ-हस्ताक्षरित अनुरोधों का उत्पादन करना है। यह बहुत से लोगों को यात्रा करता है क्योंकि ओह्त पर हस्ताक्षर करने की आवश्यकताएं विशेष रूप से होती हैं। यही सरलीकृत OAuth प्रबंधक वर्ग करता है।

टोकन अनुरोध करने के लिए उदाहरण कोड:

var oauth = new OAuth.Manager();
// the URL to obtain a temporary "request token"
var rtUrl = "https://api.twitter.com/oauth/request_token";
oauth["consumer_key"] = MY_APP_SPECIFIC_KEY;
oauth["consumer_secret"] = MY_APP_SPECIFIC_SECRET;    
oauth.AcquireRequestToken(rtUrl, "POST");

यह है । सरल। जैसा कि आप कोड से देख सकते हैं, ऑओथ मापदंडों को प्राप्त करने का तरीका एक स्ट्रिंग-आधारित इंडेक्सर के माध्यम से है, एक शब्दकोश जैसा कुछ। AcquireRequestToken विधि सेवा के URL पर एक oauth- हस्ताक्षरित अनुरोध भेजती है जो टोकन, उर्फ ​​अस्थायी टोकन का अनुरोध करता है। ट्विटर के लिए, यह URL " https://api.twitter.com/oauth/request_token " है। Oauth कल्पना कहती है कि आपको एक निश्चित तरीके (url- एन्कोड किया गया और एम्परसेंड्स द्वारा मिलाया गया), और एक lexicographically- में oauth पैरामीटर (टोकन, टोकन, टाइमस्टैम्प, कंज्यूमर_की, संस्करण और कॉलबैक) के सेट को पैक करने की आवश्यकता है। क्रमबद्ध क्रम, उस परिणाम पर एक हस्ताक्षर उत्पन्न करें, फिर उन्हीं मापदंडों को हस्ताक्षर के साथ पैक करें, नए oauth_signature पैरामीटर में संग्रहीत, एक अलग तरीके से (अल्पविराम द्वारा सम्मिलित)। OAuth प्रबंधक वर्ग आपके लिए यह स्वचालित रूप से करता है। यह नॉनवेज और टाइमस्टैम्प और संस्करण और हस्ताक्षर स्वतः उत्पन्न करता है - आपके ऐप को उस सामान की देखभाल या जागरूक होने की आवश्यकता नहीं है। बस ओउथ पैरामीटर मान सेट करें और एक सरल विधि कॉल करें। प्रबंधक वर्ग अनुरोध भेजता है और आपके लिए प्रतिक्रिया देता है।

ठीक है, फिर क्या? एक बार जब आप अनुरोध टोकन प्राप्त करते हैं, तो आप वेब ब्राउज़र यूआई को पॉप करते हैं जिसमें उपयोगकर्ता स्पष्ट रूप से अनुमोदन प्रदान करेगा। यदि आप इसे सही करते हैं, तो आप इसे एक एम्बेडेड ब्राउज़र में पॉप करेंगे। ट्विटर के लिए, इसके लिए URL " https://api.twitter.com/oauth/authorize?oauth_token= " oauth_token के साथ जोड़ा गया है। कोड में ऐसा करें:

var url = SERVICE_SPECIFIC_AUTHORIZE_URL_STUB + oauth["token"];
webBrowser1.Url = new Uri(url);

(यदि आप ऐसा बाहरी ब्राउज़र में कर रहे थे तो आप उपयोग करेंगे System.Diagnostics.Process.Start(url)।)

Url प्रॉपर्टी को सेट करने से WebBrowser नियंत्रण स्वचालित रूप से उस पृष्ठ पर नेविगेट करने का कारण बनता है।

जब उपयोगकर्ता "अनुमति दें" बटन पर क्लिक करता है तो एक नया पृष्ठ लोड किया जाएगा। यह एक HTML रूप है और यह पूर्ण ब्राउज़र की तरह ही कार्य करता है। अपने कोड में, WebBrowser नियंत्रण के DocumentedCompleted घटना के लिए एक हैंडलर पंजीकृत करें, और उस हैंडलर में पिन को पकड़ो:

var divMarker = "<div id=\"oauth_pin\">"; // the div for twitter's oauth pin
var index = webBrowser1.DocumentText.LastIndexOf(divMarker) + divMarker.Length;
var snip = web1.DocumentText.Substring(index);
var pin = RE.Regex.Replace(snip,"(?s)[^0-9]*([0-9]+).*", "$1").Trim();

यह HTML स्क्रीन स्क्रैपिंग का एक सा है।

पिन को हथियाने के बाद, आपको वेब ब्राउज़र की आवश्यकता नहीं है, इसलिए:

webBrowser1.Visible = false; // all done with the web UI

... और आप उस पर भी Dispose () कॉल करना चाह सकते हैं।

अगला कदम उस पिन के साथ एक और HTTP संदेश भेजकर एक्सेस टोकन प्राप्त कर रहा है। यह एक और हस्ताक्षरित ओउथ कॉल है, जिसे ऑउथ ऑर्डरिंग और स्वरूपण के साथ निर्मित किया गया है जो मैंने ऊपर वर्णित किया है। लेकिन OAuth.Manager वर्ग के साथ एक बार फिर यह वास्तव में सरल है:

oauth.AcquireAccessToken(URL_ACCESS_TOKEN,
                         "POST",
                         pin);

ट्विटर के लिए, वह URL " https://api.twitter.com/oauth/access_token " है।

अब आपके पास पहुंच टोकन है, और आप उन्हें हस्ताक्षरित HTTP अनुरोधों में उपयोग कर सकते हैं। ऐशे ही:

var authzHeader = oauth.GenerateAuthzHeader(url, "POST");

... जहाँ urlसंसाधन समापन बिंदु है। उपयोगकर्ता की स्थिति को अपडेट करने के लिए, यह " http://api.twitter.com/1/statuses/update.xml?status=Hello " होगा।

फिर उस स्ट्रिंग को प्राधिकरण नाम के HTTP हेडर में सेट करें ।

तृतीय-पक्ष सेवाओं के साथ बातचीत करने के लिए, TwitPic की तरह, आपको इस तरह थोड़ा अलग OAuth हेडर बनाने की आवश्यकता है :

var authzHeader = oauth.GenerateCredsHeader(URL_VERIFY_CREDS,
                                            "GET",
                                            AUTHENTICATION_REALM);

Twitter के लिए, सत्यापित क्रेडेंशियल url और realm के मान क्रमशः " https://api.twitter.com/1/account/verify_credentials.json " और " http://api.twitter.com/ " हैं।

... और उस प्राधिकरण स्ट्रिंग को एक्स-वेरिफाई-क्रेडेंशियल्स-ऑथराइजेशन नामक HTTP हेडर में डाल दिया । फिर जो भी अनुरोध भेज रहे हैं, उसे ट्विटपिक की तरह अपनी सेवा में भेजें।

बस।

सभी एक साथ, ट्विटर स्टेटस अपडेट करने का कोड कुछ इस तरह से हो सकता है:

// the URL to obtain a temporary "request token"
var rtUrl = "https://api.twitter.com/oauth/request_token";
var oauth = new OAuth.Manager();
// The consumer_{key,secret} are obtained via registration
oauth["consumer_key"] = "~~~CONSUMER_KEY~~~~";
oauth["consumer_secret"] = "~~~CONSUMER_SECRET~~~";
oauth.AcquireRequestToken(rtUrl, "POST");
var authzUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth["token"];
// here, should use a WebBrowser control. 
System.Diagnostics.Process.Start(authzUrl);  // example only!
// instruct the user to type in the PIN from that browser window
var pin = "...";
var atUrl = "https://api.twitter.com/oauth/access_token";
oauth.AcquireAccessToken(atUrl, "POST", pin);

// now, update twitter status using that access token
var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
var request = (HttpWebRequest)WebRequest.Create(appUrl);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.StatusCode != HttpStatusCode.OK)
        MessageBox.Show("There's been a problem trying to tweet:" +
                        Environment.NewLine +
                        response.StatusDescription);
}

OAuth 1.0a कवर्स के नीचे जटिल है, लेकिन इसका उपयोग करने की आवश्यकता नहीं है। OAuth.Manager निवर्तमान oauth अनुरोधों की पीढ़ी को संभालता है, और प्रतिक्रियाओं में oauth सामग्री प्राप्त करता है और प्रसंस्करण करता है। जब Request_token अनुरोध आपको एक oauth_token देता है, तो आपके ऐप को इसे संग्रहीत करने की आवश्यकता नहीं है। Oauth.Manager अपने आप करने के लिए पर्याप्त स्मार्ट है। इसी तरह जब access_token के अनुरोध पर एक्सेस टोकन और सीक्रेट वापस मिल जाता है, तो आपको उन लोगों को स्पष्ट रूप से संग्रहीत करने की आवश्यकता नहीं है। OAuth.Manager आपके लिए उस स्थिति को संभालता है।

बाद के रनों में, जब आपके पास पहले से पहुंच टोकन और रहस्य है, तो आप OAuth.Manager को इस तरह से इंस्टेंट कर सकते हैं:

var oauth = new OAuth.Manager();
oauth["consumer_key"] = CONSUMER_KEY;
oauth["consumer_secret"] = CONSUMER_SECRET;
oauth["token"] = your_stored_access_token;
oauth["token_secret"] = your_stored_access_secret;

... और फिर ऊपर के रूप में प्राधिकरण हेडर उत्पन्न करते हैं।

// now, update twitter status using that access token
var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
var request = (HttpWebRequest)WebRequest.Create(appUrl);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.StatusCode != HttpStatusCode.OK)
        MessageBox.Show("There's been a problem trying to tweet:" +
                        Environment.NewLine +
                        response.StatusDescription);
}

आप यहाँ OAuth.Manager वर्ग वाले DLL को डाउनलोड कर सकते हैं । उस डाउनलोड में एक हेल्पफाइल भी है। या आप ऑनलाइन हेल्पफाइल देख सकते हैं

यहां इस प्रबंधक का उपयोग करने वाले विंडोज फॉर्म का एक उदाहरण देखें ।


काम कर रहा उदाहरण

कमांड-लाइन टूल का कार्यशील उदाहरण डाउनलोड करें जो यहां वर्णित वर्ग और तकनीक का उपयोग करता है:


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

2
हाय चीज़ो, अपने कोड और अपने विस्तृत विवरण को साझा करने के लिए धन्यवाद। आपने एक महान अभी तक सरल समाधान प्रदान किया। हालांकि, आप गैर "ओओबी" समाधानों का समर्थन करने के लिए अपने गेटसिग्नेचरबेस विधि में एक छोटा सा बदलाव करना चाहते हैं। गैर "oob" के लिए, आपको URL को कॉलबैक एन्कोड करना होगा, इसलिए जब आप इसके माध्यम से पुनरावृत्ति कर रहे हों, तो आप कुछ इस तरह जोड़ना चाहेंगे। यदि आप (p1.Key == "कॉलबैक") {p.Add ( "oauth_" + p1.Key, UrlEncode (p1.Value) आदि); जारी रखें;}
जॉनी ओशिका

1
यह OAuth 2.0 के लिए काम नहीं करता है। यह वर्ग OAuth 1.0a के लिए है। OAuth2.0 उपयोग करने के लिए काफी सरल है, क्योंकि विभिन्न मापदंडों पर कोई हस्ताक्षर और लेक्सोग्राफिक सॉर्टिंग नहीं है। तो आपको शायद OAuth 2.0 करने के लिए किसी बाहरी वर्ग की आवश्यकता नहीं है, या ... यदि आपको बाहरी वर्ग की आवश्यकता है, तो यह इस की तुलना में बहुत सरल होने वाला है।
चीजो

1
helpfile ऑनलाइन नहीं मिली: cheeso.members.winisp.net/OAuthManager1.1
किकेनेट

3
सभी लिंक टूटे हुए दिखाई देते हैं। मुझे यहाँ एक प्रति मिली: gist.github.com/DeskSupport/2951522#file-oauth-cs
John
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.