Windows Live Writer の WSSE 認証

慌ただしかった4週間のインターンもようやく終わり・・・、明日からは9月のインターンの開始です。
さて、8月にid:keikubo, id:hakobe932 とダイアリーに「下書き機能」と「AtomPub」(と「その場削除」)をリリースしたのですが(二人ともお疲れ様でした!)、id:keikuboの日記にAtomPubがうまくいかない、というコメントがついていたので調べてみました。

どこで失敗するかというと、Windows Live Writerに新しいアカウントを追加する際。FiddlerWLWの通信を覗いてみたところ、アカウントの追加画面でBlogのタイプをAtom Pub APIに設定し、エンドポイントURLを入力してやって次の画面に進もうとすると、WLWはそのエンドポイントURLに対してまず認証無しでGETリクエストを投げるようです。当然はてなAtom Pub APIはこれを拒否し、401 Unauthorizedを返すのですが、imageこれに対してWLWは今度はちゃんとWSSE認証のためのヘッダを付けてGETリクエストを送るようです。 良い感じですね。ところがこれに対してはてなAtom Pubは403 Forbiddenを返してきます。なんで?

調べた環境は、Windows XPWindows Live Writer をインストール。HTTPヘッダの情報はFiddler2で監視しました。
WSSE認証では、リクエストヘッダに以下の情報を必要とします

X-WSSE: UsernameToken Username="xxxx", PasswordDigest="xxxx", Created="xxxx", Nonce="xxxx"

サービス提供側は、預かっているパスワードとこのリクエストを以下のチェックにかけます。

PasswordDigest = base64(sha1(Nonce . Created . パスワード)) 

リクエストのNonceとはHTTPリクエスト毎に生成したセキュリティ・トークンで、リクエスト時はBASE64エンコードして送信します。サーバー側ではこれをデコードしてチェックしているので、実際はこのようになります。

PasswordDigest = base64(sha1(base64_decode(Nonce) . Created . パスワード)) 

結論から言うと、Windows Live Writer は、NonceにBASE64エンコードされた文字列を送信してきますが、これをデコードせずそのままチェックすると通りました。
今回いろいろ調べたところ、もともとWSSE認証のNonceの扱いは仕様が明確でなかったため、クライアントによってはエンコードせずに送る仕様のものがあったりするようです。今回の Windows Live Writer はBASE64エンコードされた文字列を送ってきて、デコードするな、というのは微妙な仕様な気もしますが、これに対応し、送信された文字列をBASE64デコードしたものとそのままと両方のチェックをするようにしました。
これはWSSE認証のFAQだったようですね。はてなでこれまでWSSE認証を使用しているサービスは、ブックマーク、グラフなどがあったのですが、どれもBASE64デコードしたもののチェックしかしてこなかったのですが、あまり問題になっていませんでした。
これは、ブログサービスでWSSE認証に対応したのが今回が初めてだったので、普通のブログ投稿クライアントソフトが利用されてこなかったからでしょうね。投稿できなかった方は申し訳ありませんでしたが再度お試しいただければと思います。
というわけで、どうぞご利用ください!と思ったら、Windows Live Writer が認証に一度通った後にX-WSSEヘッダを付加せずにPOSTしてくる事があったりして、投稿が安定しません(ヘッダ付でPOSTする事もある)。
僕の環境依存かもしれませんが、これ以上はこちらでは対処しようが無いので、うまく動作しない場合は別のクライアントソフトをご利用いただくなどしていただいた方がいいかもしれません。

追記

http://blog.sharplab.net/computer/cprograming/windowslivewriter/921/ の方は現在では使えているそうです。ということはうまくいかないのはやっぱり僕の環境依存かもしれません。