OAuth z weryfikacją in.NET

Próbuję stworzyć aplikację kliencką. NET (w WPF-choć na razie robię to tylko jako aplikacja konsolowa), aby zintegrować ją z aplikacją obsługującą OAuth, w szczególności Mendeley ( http://dev.mendeley.com ), który najwyraźniej używa trójnogiego OAuth.

To mój pierwszy raz przy użyciu OAuth, i mam wiele trudności, aby rozpocząć z nim. Znalazłem kilka bibliotek OAuth lub helperów. NET, ale wydają się być bardziej skomplikowane, niż myślę, że potrzebuję. All I chcesz zrobić to móc wysyłać prośby o odpoczynek do API Mendeley i uzyskiwać odpowiedzi z powrotem!

Do tej pory próbowałem:

Pierwszy (DotNetOpenAuth) wydaje się, że mógłby zrobić to, czego potrzebowałem, jeśli spędziłem wiele godzin próbując wypracować jak. Drugi i trzeci, z tego co wiem, nie wspierają kody weryfikacyjne, które Mendeley odsyła -- chociaż mogę się mylić co do tego:)

Mam klucz konsumencki i sekret od Mendeley, a dzięki DotNetOpenAuth udało mi się uruchomić przeglądarkę ze stroną Mendeley dostarczającą kod weryfikacyjny dla użytkownika, aby wejść do aplikacji. Jednak w tym momencie zgubiłem się i nie mogłem wymyślić, jak rozsądnie zapewnić to z powrotem do aplikacji.

Bardzo chętnie przyznam, że nie mam pojęcia od czego zacząć to (choć wydaje się, że jest dość stroma krzywa uczenia się) - jeśli ktoś może wskazać mi właściwy kierunek, byłbym wdzięczny!

Author: thomson_matt, 2010-10-23

1 answers

Zgadzam się z Tobą. Klasy wsparcia open-source OAuth dostępne dla aplikacji. Net są trudne do zrozumienia, zbyt skomplikowane (ile metod jest narażonych przez DotNetOpenAuth?), źle zaprojektowane (spójrz na metody z 10 parametrami łańcuchowymi w OAuthBase.moduł cs z tego linku google który podałeś - w ogóle nie ma zarządzania państwem) , lub w inny sposób niezadowalający.

To nie musi być takie skomplikowane.

Nie jestem ekspertem od OAuth, ale wyprodukowałem OAuth client-side Manager class, który z powodzeniem używam z Twitterem i TwitPic. Jest stosunkowo prosty w użyciu. To jest open source i dostępne tutaj: Oauth.cs

Do recenzji w OAuth 1.0 a...trochę zabawne, jest specjalna nazwa i wygląda jak "standard", ale z tego co wiem, jedyną usługą, która implementuje "OAuth 1.0 a" jest Twitter. To chyba standard wystarczy . ok, w każdym razie w OAuth 1.0 a, sposób działania dla aplikacji desktopowych jest taki:

  1. Ty, twórca aplikacji, zarejestruj aplikację i uzyskaj "klucz konsumenta" i "sekret konsumenta". Na Arstechnica jest dobrze napisana analiza, dlaczego ten model nie jest najlepszy , ale jak mówią, jest jaki jest .

  2. Twoja aplikacja działa. Po pierwszym uruchomieniu, musi zmusić użytkownika do wyraźnego zatwierdzenia aplikacji do składania wniosków o odpoczynek uwierzytelnionych oauth do Twittera i jego siostrzanych usług (takich jak TwitPic). Do zrobienia musisz przejść przez proces zatwierdzania, obejmujący wyraźną zgodę użytkownika. Dzieje się tak tylko przy pierwszym uruchomieniu aplikacji. Tak:

    • request a "request token". Aka tymczasowy token.
    • pop stronę internetową, przekazując token żądania jako param zapytania. Ta strona internetowa przedstawia interfejs użytkownika do użytkownika z pytaniem " czy chcesz przyznać dostęp do tej aplikacji?"
    • Użytkownik loguje się na stronę internetową Twittera i udziela lub odmawia dostępu.
  3. odpowiedź pojawia się strona html. Jeśli użytkownik udzielił dostępu, wyświetlany jest kod PIN w czcionce 48-pt
  4. Użytkownik musi teraz wyciąć / wkleić ten pin do okna formularza i kliknąć "Dalej" lub coś podobnego.
  5. Następnie aplikacja komputerowa wykonuje uwierzytelnione oauth żądanie "tokena dostępu". Kolejna Prośba o odpoczynek.
  6. aplikacja komputerowa otrzymuje "token dostępu" i "sekret dostępu".

Po zatwierdzeniu, aplikacja desktopowa może po prostu użyj "tokena dostępu" i "tajemnicy dostępu" (wraz z "kluczem konsumenckim" i "tajemnicą konsumenta" specyficznym dla aplikacji), aby wykonywać uwierzytelnione żądania w imieniu użytkownika na Twitterze. Nie wygasają one, chociaż jeśli użytkownik dezautoryzuje aplikację lub jeśli Twitter z jakiegoś powodu dezautoryzuje Twoją aplikację, lub jeśli stracisz token dostępu i / lub sekret, będziesz musiał ponownie wykonać taniec zatwierdzenia.


Jeśli nie jesteś sprytny, interfejs użytkownika może odzwierciedlać wieloetapowy OAuth przepływ wiadomości. Jest lepszy sposób.

Użyj kontrolki WebBrowser i otwórz stronę autoryzacji w aplikacji komputerowej. Gdy użytkownik kliknie "Zezwól", chwyć tekst odpowiedzi z kontrolki WebBrowser, wyodrębnij automatycznie PIN, a następnie uzyskaj tokeny dostępu. Wysyłasz 5 lub 6 żądań HTTP, ale użytkownik musi zobaczyć tylko jedno okno Zezwalaj/odmawiaj. Proste.

Like this:
alt text


Jeśli masz uporządkowany interfejs, pozostaje tylko wyzwanie do tworzenia żądań podpisanych oauth. To podchodzi do wielu ludzi, ponieważ wymagania dotyczące podpisywania oauth są trochę szczególne. To właśnie robi uproszczona Klasa OAuth Manager.

Przykładowy kod do żądania tokena:

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");

TO JEST TO . Proste. Jak widać z kodu, sposób na dotarcie do parametrów oauth jest za pomocą indeksatora opartego na łańcuchach, coś w rodzaju słownika. Metoda AcquireRequestToken wysyła żądanie podpisane oauth na adres URL usługi, który tokeny wniosków o dotacje, aka tokeny tymczasowe. W przypadku Twittera ten adres URL to " https://api.twitter.com/oauth/request_token ". Specyfikacja oauth mówi, że musisz spakować zestaw parametrów oauth (token, token_secret, nonce, timestamp, consumer_key, version I callback), w określony sposób (zakodowany url i dołączony przez ampersands) i w uporządkowanej leksykograficznie kolejności, wygenerować podpis na tym wyniku, a następnie spakować te same parametry wraz z podpisem, zapisanym w Nowym pliku. parametr oauth_signature, w inny sposób (połączony przecinkami). Klasa OAuth manager robi to za ciebie automatycznie. automatycznie generuje nonces i znaczniki czasu oraz wersje i sygnatury - Twoja aplikacja nie musi się tym przejmować ani być tego świadoma. Wystarczy ustawić wartości parametrów oauth i wykonać proste wywołanie metody. Klasa manager wysyła żądanie i przetwarza odpowiedź za Ciebie.

Ok, to co? Gdy otrzymasz token żądania, wyskakujesz interfejs przeglądarki internetowej, w którym użytkownik wyraźnie zatwierdzi. Jeśli zrobisz to dobrze, pojawi się to w wbudowanej przeglądarce. W przypadku Twittera adres URL to " https://api.twitter.com/oauth/authorize?oauth_token= " z dodanym oauth_token. Zrób to w kodzie Tak:
var url = SERVICE_SPECIFIC_AUTHORIZE_URL_STUB + oauth["token"];
webBrowser1.Url = new Uri(url);

(jeśli robisz to w zewnętrznej przeglądarce, używasz System.Diagnostics.Process.Start(url).)

Ustawienie właściwości Url powoduje, że kontrolka WebBrowser automatycznie przechodzi do tej strony.

Gdy użytkownik kliknie przycisk "Zezwól", zostanie załadowana nowa strona. Jest to formularz HTML i działa tak samo jak w pełnej przeglądarce. W kodzie zarejestruj funkcję obsługi dla zdarzenia DocumentedCompleted kontrolki WebBrowser i w tej funkcji chwyć kod pin:

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();

To trochę skrobanie ekranu HTML.

Po pobraniu Pina nie potrzebujesz już przeglądarki internetowej, więc:

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

...możesz też wywołać Dispose ().

Następnym krokiem jest uzyskanie tokena dostępu, wysyłając kolejną wiadomość HTTP wraz z tym pinem. Jest to kolejne podpisane wywołanie oauth, zbudowane z OAuth ordering i formatowanie, które opisałem powyżej. Ale po raz kolejny jest to naprawdę proste z OAuth.Klasa menedżera:

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

Dla Twittera, ten adres URL to " https://api.twitter.com/oauth/access_token".

Teraz masz tokeny dostępu i możesz ich używać w podpisanych żądaniach HTTP. W ten sposób:

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

...gdzie url jest punktem końcowym zasobu. Aby zaktualizować status użytkownika, będzie to " http://api.twitter.com/1/statuses/update.xml?status=Hello".

Następnie Ustaw ten łańcuch w nagłówku HTTP o nazwie Authorization .

Aby wejść w interakcję z usługami innych firm, takimi jak TwitPic, musisz skonstruować nieco inny nagłówek OAuth, jak ten:
var authzHeader = oauth.GenerateCredsHeader(URL_VERIFY_CREDS,
                                            "GET",
                                            AUTHENTICATION_REALM);

Dla Twittera wartości adresu URL i realm verify creds są " https://api.twitter.com/1/account/verify_credentials.json" i " http://api.twitter.com / "

...i umieść ten łańcuch autoryzacji w nagłówku HTTP o nazwie x-Verify-Credentials-Authorization. Następnie wyślij to do swojego serwisu, jak TwitPic, wraz z każdą prośbą, którą wysyłasz.

To jest to.

Razem kod do aktualizacji statusu Twittera może wyglądać mniej więcej tak:

// 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.0 a jest trochę skomplikowane pod przykrywką, ale korzystanie z niego nie musi być. OAuth.Manager zajmuje się generowaniem wychodzących zapytań oauth oraz odbieraniem i przetwarzaniem treści OAuth w odpowiedziach. Gdy żądanie Request_token daje oauth_token, aplikacja nie musi go przechowywać. Oauth.Menedżer jest na tyle sprytny, że robi to automatycznie. Podobnie, gdy żądanie access_token zwróci token dostępu i sekret, nie musisz / align = "left" / OAuth.Kierownik zajmuje się tym stanem.

W kolejnych uruchomieniach, gdy masz już token dostępu i sekret, możesz utworzyć instancję OAuth.Manager jak ten:

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;

...a następnie Wygeneruj nagłówki autoryzacji jak powyżej.

// 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);
}

Możesz pobrać DLL zawierający OAuth.Klasa menedżera tutaj . W tym pliku znajduje się również plik pomocy. Możesz też wyświetlić plik pomocy online .

Zobacz przykład formularza Windows, który używa tego menedżera tutaj .


PRZYKŁAD ROBOCZY

Pobierz działający przykład narzędzia wiersza poleceń, które wykorzystuje klasę i technikę opisaną tutaj:

 161
Author: Cheeso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-14 16:57:48