Eu concordo com você. As classes de suporte OAuth de código aberto disponíveis para aplicativos .NET são difíceis de entender, excessivamente complicadas (quantos métodos são expostos pelo DotNetOpenAuth?), Mal projetadas (veja os métodos com 10 parâmetros de string no módulo OAuthBase.cs desse google link que você forneceu - não há gerenciamento de estado), ou de outra forma insatisfatório.
Não precisa ser tão complicado.
Não sou um especialista em OAuth, mas produzi uma classe de gerenciador do lado do cliente OAuth, que uso com sucesso com Twitter e TwitPic. É relativamente simples de usar. É código aberto e está disponível aqui: Oauth.cs
Para análise, no OAuth 1.0a ... meio engraçado, há um nome especial e parece um "padrão", mas até onde eu sei o único serviço que implementa "OAuth 1.0a" é o Twitter. Eu acho que isso é padrão o suficiente . ok, de qualquer maneira, no OAuth 1.0a, a maneira como funciona para aplicativos de desktop é esta:
Você, o desenvolvedor do aplicativo, registra o aplicativo e obtém uma "chave do consumidor" e um "segredo do consumidor". Na Arstechnica, há uma análise bem escrita de por que esse modelo não é o melhor , mas como dizem, é o que é .
Seu aplicativo é executado. Na primeira vez em que é executado, ele precisa fazer com que o usuário conceda explicitamente a aprovação para que o aplicativo faça solicitações REST autenticadas oauth para o Twitter e seus serviços irmãos (como TwitPic). Para fazer isso, você deve passar por um processo de aprovação, envolvendo a aprovação explícita do usuário. Isso acontece apenas na primeira vez que o aplicativo é executado. Como isso:
- solicitar um "token de solicitação". Token temporário conhecido.
- pop uma página da web, passando esse token de solicitação como um parâmetro de consulta. Esta página da web apresenta a IU ao usuário, perguntando "deseja conceder acesso a este aplicativo?"
- o usuário efetua login na página da web do Twitter e concede ou nega o acesso.
- a página html de resposta aparece. Se o usuário concedeu acesso, há um PIN exibido em uma fonte de 48 pontos
- o usuário agora precisa cortar / colar aquele alfinete em uma caixa de formulário do Windows e clicar em "Avançar" ou algo semelhante.
- o aplicativo de desktop então faz uma solicitação autenticada oauth para um "token de acesso". Outra solicitação REST.
- o aplicativo de desktop recebe o "token de acesso" e o "segredo de acesso".
Após a dança da aprovação, o aplicativo de desktop pode apenas usar o "token de acesso" e o "segredo de acesso" específicos do usuário (junto com a "chave do consumidor" e o "segredo do consumidor" específicos do aplicativo) para fazer solicitações autenticadas em nome do usuário para o Twitter. Eles não expiram, embora se o usuário desautorizar o aplicativo, ou se o Twitter por algum motivo desautorizar seu aplicativo, ou se você perder seu token de acesso e / ou segredo, você precisará fazer a dança de aprovação novamente .
Se você não for inteligente, o fluxo de IU pode espelhar o fluxo de mensagens OAuth de várias etapas. Há um caminho melhor.
Use um controle WebBrowser e abra a página da web de autorização no aplicativo de desktop. Quando o usuário clicar em "Permitir", pegue o texto de resposta desse controle WebBrowser, extraia o PIN automaticamente e obtenha os tokens de acesso. Você envia 5 ou 6 solicitações HTTP, mas o usuário precisa ver apenas uma única caixa de diálogo Permitir / Negar. Simples.
Como isso:
Se você classificou a IU, o único desafio que resta é produzir solicitações assinadas oauth. Isso confunde muitas pessoas porque os requisitos de assinatura oauth são meio particulares. É isso que a classe simplificada do OAuth Manager faz.
Código de exemplo para solicitar um token:
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");
É ISSO . Simples. Como você pode ver no código, a maneira de chegar aos parâmetros oauth é por meio de um indexador baseado em string, algo como um dicionário. O método AcquireRequestToken envia uma solicitação assinada oauth para a URL do serviço que concede tokens de solicitação, também conhecidos como tokens temporários. Para o Twitter, este URL é " A classe do gerenciador OAuth faz isso para você automaticamente. Ela gera nonces e carimbos de data / hora e versões e assinaturas automaticamente - seu aplicativo não precisa se preocupar ou estar ciente dessas coisas. Basta definir os valores do parâmetro oauth e faça uma chamada de método simples. a classe de gerenciador envia a solicitação e analisa a resposta para você. https://api.twitter.com/oauth/request_token ". A especificação oauth diz que você precisa empacotar o conjunto de parâmetros oauth (token, token_secret, nonce, timestamp, consumer_key, version e callback), de uma certa maneira (url-codificado e unido por e comercial), e em um lexicograficamente- ordenada, gere uma assinatura nesse resultado e, em seguida, empacote esses mesmos parâmetros junto com a assinatura, armazenados no novo parâmetro oauth_signature, de uma maneira diferente (unidos por vírgulas).
Ok, então o quê? Depois de obter o token de solicitação, você abre a IU do navegador da web, na qual o usuário concederá a aprovação explicitamente. Se você fizer isso direito, você o colocará em um navegador integrado. Para o Twitter, a URL é " https://api.twitter.com/oauth/authorize?oauth_token= " com o oauth_token anexado. Faça isso em código como:
var url = SERVICE_SPECIFIC_AUTHORIZE_URL_STUB + oauth["token"];
webBrowser1.Url = new Uri(url);
(Se você estivesse fazendo isso em um navegador externo, você usaria System.Diagnostics.Process.Start(url)
.)
Definir a propriedade Url faz com que o controle WebBrowser navegue para essa página automaticamente.
Quando o usuário clica no botão "Permitir", uma nova página é carregada. É um formulário HTML e funciona da mesma forma que em um navegador completo. Em seu código, registre um manipulador para o evento DocumentedCompleted do controle WebBrowser e, nesse manipulador, pegue o pino:
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();
Isso é um pouco de raspagem de tela HTML.
Depois de pegar o pino, você não precisa mais do navegador da web, então:
webBrowser1.Visible = false; // all done with the web UI
... e você pode querer chamar Dispose () nele também.
A próxima etapa é obter o token de acesso, enviando outra mensagem HTTP junto com esse pin. Esta é outra chamada oauth assinada, construída com a ordenação e formatação oauth que descrevi acima. Mas, mais uma vez, isso é realmente simples com a classe OAuth.Manager:
oauth.AcquireAccessToken(URL_ACCESS_TOKEN,
"POST",
pin);
Para o Twitter, esse URL é " https://api.twitter.com/oauth/access_token ".
Agora você tem tokens de acesso e pode usá-los em solicitações HTTP assinadas. Como isso:
var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
... onde url
está o endpoint do recurso. Para atualizar o status do usuário, seria " http://api.twitter.com/1/statuses/update.xml?status=Hello ".
Em seguida, defina essa string no cabeçalho HTTP denominado Authorization .
Para interagir com serviços de terceiros, como TwitPic, você precisa construir um cabeçalho OAuth ligeiramente diferente , como este:
var authzHeader = oauth.GenerateCredsHeader(URL_VERIFY_CREDS,
"GET",
AUTHENTICATION_REALM);
Para o Twitter, os valores para o url e o reino dos creds de verificação são " https://api.twitter.com/1/account/verify_credentials.json " e " http://api.twitter.com/ " respectivamente.
... e coloque essa string de autorização em um cabeçalho HTTP chamado X-Verify-Credentials-Authorization . Em seguida, envie isso para o seu serviço, como TwitPic, junto com qualquer solicitação que você está enviando.
É isso aí.
Juntos, o código para atualizar o status do Twitter pode ser algo assim:
// 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 é meio complicado nos bastidores, mas usá-lo não precisa ser. O OAuth.Manager lida com a geração de solicitações oauth de saída e o recebimento e processamento de conteúdo oauth nas respostas. Quando a solicitação Request_token fornece um oauth_token, seu aplicativo não precisa armazená-lo. O Oauth.Manager é inteligente o suficiente para fazer isso automaticamente. Da mesma forma, quando a solicitação access_token recebe de volta um token de acesso e segredo, você não precisa armazená-los explicitamente. O OAuth.Manager trata desse estado para você.
Nas execuções subsequentes, quando você já tiver o token de acesso e o segredo, poderá instanciar o OAuth.Manager assim:
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;
... e então gere cabeçalhos de autorização como acima.
// 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);
}
Você pode baixar uma DLL contendo a classe OAuth.Manager aqui . Há também um arquivo de ajuda nesse download. Ou você pode ver o arquivo de ajuda online .
Veja um exemplo de Windows Form que usa este gerenciador aqui .
EXEMPLO DE TRABALHO
Baixe um exemplo funcional de uma ferramenta de linha de comando que usa a classe e a técnica descritas aqui: