ASP.NET Core 2.0でWebAPIにXSRF対策を仕込む
今日はASP.NET Core 2.0でWebAPIのコントローラーのアクションが起動するまえにXSRF対策の事前チェックを行う方法を調べていました。
HTMLのform要素をPOSTリクエストの送信元とする場合については情報も多くありました。しかし、jQueryのような低レベルのAPIであれAngularのようなフルスタックなフレームワークが提供する高レベルのAPIであれ、JavaScriptコードを送信元とする場合についてはあまり情報がありません。
Web上で紹介されている方法としては2つ。1つ目はASP.NET Coreフレームワークによりform要素内に書き出されたXRSFトークンをJavaScriptコードから取得してAjaxリクエストに使用するもの。2つ目は特定のパスにアクセスしたときだけCookieのエントリーとしてXSRFトークンをクライアントに発行し、クライアント側のJavaScriptコードからこれを取得してAjaxリクエストに使用するもの。
情報量としては前者の方が多かったです。しかし、この方法ではViewをレンダリングするアプリケーションとWebAPIを提供するアプリケーションは同一でないといけないのです。シンプルには違いないものの、どこか理屈というか哲学というかに引っかかるところがあります。ViewとWebAPIをなるべく疎結合にしたいと考えるなら、後者の方を選ぶことになると思います。
後者の方法はこちらで紹介されていました。このWebページの例ではAntiforgeryTokenMiddleware
というミドルウェア・クラスを定義して、「HTTPリクエストを解析して特定のパスに対するリクエストであったら、XSRFトークンを新規作成、HTTPレスポンスのSet-Cookieヘッダーを通じてクライアントに渡す」というロジックを記述しています。そしてこのミドルウェアをStartup.Configure(IApplicationBuilder, IHostingEnvironment)
でアプリケーションに組み込んでいます。
一方でConfigureServices(IServiceCollection services)
ではクライアントからのHTTP要求時にトークンがどこに格納されて送信されてくるかを指定しています。これをあえてしないとフレームワークはトークンがフォーム・データとしてHTTP要求本文の一部として送信されてくることを前提とした動きをしてしまうとのこと。
わかればどうということもない、ほんの少しのコードで実現できるのですが、意外と情報が少ないので苦戦しました。