« 04月05日のココロ日記(BlogPet) | トップページ | 04月13日のココロ日記(BlogPet) »
2009.04.07
C# で OAuth
C# で OAuth 認証対応アプリケーションを書くときは、"oauth - Google Code" の OAuthBase.cs を使うと、かなり楽に書けます。この OAuthBase.cs には、OAuth を実装する上でいちばんややこしい「signature を生成する処理」が入っています。
この OAuthBase.cs を利用しているものとしては、
- Twitter に OAuth 経由でアクセスするWebアプリケーションの例
Twitter oAuth with .NET | Shannon Whitley - MySpace の REST API を OAuth 越しに使うアプリケーションの例
Steven Ng » Blog Archive » Using MySpace REST API with OAuth and C#
などがあります。
私は、Twitter oAuth with .NET | Shannon Whitley を参考にしつつ、tumblen3 に、Twitter の API を OAuth 越しに使う処理を 組み込んでみました。(Webアプリケーションではなく、)デスクトップアプリケーションで OAuth 認証を使う例になっています。Webアプリケーションの実装例は巷に多数ありますが、デスクトップクライアントの実装例はまだほとんどないので、クライアントを作ろうとしている人には参考になるのではないかと思います。なお、デスクトップアプリケーション(デスクトップクライアント)で OAuth 認証を使うためのあれこれは、後日、別途、記事を書く予定です。
で、今回、signature を生成するのに OAuthBase.cs を利用しているのですが、「リクエストトークンの取得」から「アクセストークンの取得」までは問題なく動きました。API の OAuth 越しでの実行も、Twitter の timeline の取得、favorite の登録、ダイレクトメッセージの受信、と、ここまでは順調に動きました。このまま何の問題もなく他の API も動くのかと思いきや、「つぶやきの投稿」で 401 Unauthorized (認証失敗) のエラーが発生。投稿内容をいろいろ変えて試してみた結果、英数字だけのつぶやきは問題なく投稿できるものの、漢字が混じると「認証失敗」になることがわかりました。なんで認証失敗になるのかというと、こちらで生成した signature と Twitter側で生成した signature が一致しないのが原因であることが判明。詳しく調べてみたところ、OAuthBase.cs 内の URLエンコード(パーセントエンコード)処理 OAuthBase.UrlEncode(string value) がマルチバイト文字のことをまったく考慮せずにコーディングされていることを突き止めました。
/// <summary>
/// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case.
/// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth
/// </summary>
/// <param name="value">The value to Url encode</param>
/// <returns>Returns a Url encoded string</returns>
protected string UrlEncode(string value)
{
StringBuilder result = new StringBuilder();
foreach (char symbol in value)
{
if (unreservedChars.IndexOf(symbol) != -1)
{
result.Append(symbol);
}
else
{
result.Append('%' + String.Format("{0:X2}", (int)symbol));
}
}
return result.ToString();
}
結局、以下のような、 OAuthBase.UrlEncode(string value, Encoding encode) というメソッドを書いて対応しました。
protected string UrlEncode(string value, Encoding encode)
{
StringBuilder result = new StringBuilder();
byte[] data = encode.GetBytes(value);
int len = data.Length;
for (int i = 0; i < len; i++)
{
int c = data[i];
if (c < 0x80 && unreservedChars.IndexOf((char)c) != -1)
{
result.Append((char)c);
}
else
{
result.Append('%' + String.Format("{0:X2}", (int)data[i]));
}
}
return result.ToString();
}
ということで、もし、OAuthBase.cs を使っていて、「認証失敗」のまま先に進めていない人がいるようでしたら、上記のコードを使ってみてください。
関連記事
投稿者: tsupo 2009.04.07 午前 03:01
| 固定リンク
|
|
|
|
|
| ![]()
|
|
|
|
|
|
「プログラミング」カテゴリ内の最近の記事
アマゾンわくわく探検隊
トラックバック
この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/6737/44592074
この記事へのトラックバック一覧です: C# で OAuth:
コメント
Jaikuにはポストできるんですが、Twitterには「abc!@#」などのアルファベットだけではポストできるのにマルチバイトになると401エラー(シグネチャが合わない?)になってしまい悩んでます。
たとえば、「あ」status=%E3%81%82(シグネチャ算出時:status%3D%25E3%2581%2582)
とするとダメです。
「abc!@#」status=abc%21%40%23(シグネチャ算出時:status%3Dabc%2521%2540%2523)
だとOKなんですが><
投稿者: kichi (2009.04.12 午前 04:18)
2009年4月12日のいつごろからかわかりませんが、Twitter のサーバ側の OAuth の(クライアント側のsignatureと照合するための)signature生成処理がおかしいようです。シングルバイト文字のみの場合は問題なく投稿できますが、マルチバイト文字が含まれる場合は 401 エラーになるようです。
すでに、問題は Twitter に報告されているようで、現在、Twitter 側の対応(修正)待ちです。
投稿者: tsupo (2009.04.14 午前 12:12)




