質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.03%

Spring Securityを用いたCSRF対策の実現方法

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,771
退会済みユーザー

退会済みユーザー

Spring SecurityでCSRF対策機能だけ使うには、どのような記述をxmlファイルに追加すればいいのでしょうか?

現在、Spring MVC 4.3.2を用いてWebアプリケーションを作成しています。ユーザー登録・ログイン・ログアウト機能などを、自前で実装し終わったところで、ユーザー登録・ログインフォームにCSRF対策を施したいと考えました。これも自前で実装しても良いのですが、Spring SecurityにCSRF対策を自動で行ってくれる機能があるようなので、それを使うことにしました。Spring Securityの最新版をMavenの依存性に追加し、Web上の情報にしたがって以下の設定をSpringのxmlファイルに追記しました。

<security:http auto-config="true"/>

この状態でアプリケーションを起動したところ、以下のエラーメッセージが表示されました。

org.springframework.beans.factory.NoSuchBeanDefinitionException:
    No bean named 'org.springframework.security.authenticationManager' is defined:
    Did you forget to add a global <authentication-manager> element to your configuration (with child <authentication-provider> elements)?
    Alternatively you can use the authentication-manager-ref attribute on your <http> and <global-method-security> elements.

そこで、xmlファイルの追加記述を以下のように変更しました。

<security:http auto-config="true"/>
<security:authentication-manager/>

この変更でエラーは出ないようになったのですが、CSRFトークンがHTMLに挿入されておらず、困っています。ちなみに、web.xmlの方にはDelegatingFilterProxyを追加済みです。

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

ご回答よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • A-pZ

    2016/08/11 21:33

    http://ja.stackoverflow.com/questions/28196/spring-security%E3%81%AB%E3%82%88%E3%82%8Bcsrf%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E7%8F%BE%E6%96%B9%E6%B3%95 にも投稿されていましたのでコメントをしていますが、対象のHTMLないしはJSPも書くと回答が得られるのではないでしょうか。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2016/08/11 21:38

    コメントありがとうございます。Thymeleafの方にも修正が必要でしたが、それだけではないようでした。自己解決したので、解決した方法を投稿しました。

    キャンセル

回答 1

check解決した方法

+1

自己解決しました。

まず、web.xmlに書くDelegatingFilterProxyですが、質問文に記載してあるものは私がspring-sessionを使うために設定したものでした。てっきりfilter-classが同じなので追加する必要はないと思っていたのですが、filter-nameによって識別されるようで、Spring Security用にspringSecurityFilterChainというfilter-nameでfilterを作成する必要があるようです。

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

この状態で、Spring Security自体は動くようになったと言えます。しかしながら、bean定義のxmlのほうがこれだとまだ不十分で、今のままだと、どのページにアクセスしようとしてもログインを促されてしまいます(表示されるページはSpring Securityによって用意されたものと思われます)。そこで、http要素を以下のように書き換えます。

<security:http>
    <security:form-login login-page="/login" login-processing-url="login"/>
</security:http>

ここで、login-pageはログインするページのURL、login-processing-urlはログインフォームのsubmit先です。

最後に、公式ドキュメントには

If you are using Spring MVC <form:form> tag or Thymeleaf 2.1+ and are using @EnableWebSecurity, the CsrfToken is automatically included for you (using the CsrfRequestDataValueProcessor).

と書いてありますが、自動でinputタグが作られるわけではなく、自分でCSRFトークンを入れるinputタグを作ってやらなければならないようです(使用していたのはThymeleaf 2.1.5)。

<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる