Spring MVC

Spring MVCでSpring SecurityのCSRFトークンチェックを変更しエラー制御を追加してみた

今回は、Spring MVC上のSpring Securityを利用したプログラムに、Spring Bootの場合に実装していた、Spring Securityのリクエスト毎にCSRFトークンを変える処理とSpring Securityのエラー処理を追加してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること。

Spring MVCでSpring Securityを利用してみた今回は、Spring MVC上でSpring Securityを利用して、独自ログイン画面による認証処理を実装してみたので、そのサンプル...

流用ソース

Spring Bootを使っていた、下記記事のソースコードを流用するものとする。

Spring Boot上でSpring Securityのエラー処理を追加してみた今回は、Spring Securityでエラーが発生した場合に、エラー画面に遷移する処理を追加してみたので、そのサンプルプログラムを共有...

サンプルプログラムの作成

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、「前提条件」のプログラムから変更したプログラムである。

Spring Securityの定義を行うXMLファイルの内容は以下の通りで、前提条件のプログラムに、エラー制御と、CSRFトークンチェックをリクエスト毎に行う対応を追加し、流用ソースの「DemoSecurityConfig.java」と同じような内容を実装している。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:sec="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/security
         http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- ログイン画面のcssファイルとしても共通のdemo.cssを利用するため、 -->
    <!-- src/main/webapp/resources/static/cssフォルダ下は常にアクセス可能とする -->
	<sec:http pattern="/resources/static/css/**" security="none"/>
	
    <sec:http>
    	<!-- ログイン画面は常にアクセス可能とする -->
        <sec:intercept-url pattern="/login" access="permitAll" />
        <!-- それ以外の画面は全て認証を有効にする -->
        <sec:intercept-url pattern="/**" access="isAuthenticated()" />
        <!-- ログインに成功したら検索画面に遷移する -->
        <sec:form-login login-page="/login" default-target-url="/" />
        <!-- ログアウト時はログイン画面に遷移する -->
        <sec:logout logout-success-url="/login" />
        <!-- エラー発生時はエラー画面に遷移する -->
        <sec:access-denied-handler error-page="/toError" />
        <!-- CSRFトークンのリポジトリを設定する -->
        <sec:csrf token-repository-ref="csrfTokenRepository" />
        <!-- CSRFトークンのセッションキーをリクエスト毎に更新する処理を、 -->
        <!-- CsrfFilter(CSRFトークンチェックを行うFilter)が呼ばれる前に
             実行するようにする -->
        <sec:custom-filter ref="updSessionCsrfFilter" before="CSRF_FILTER" />
        <!-- CSRFトークンをリクエスト毎に更新する処理を、 -->
        <!-- CsrfFilterが呼ばれた後に実行するようにする -->
        <sec:custom-filter ref="chgCsrfTokenFilter" after="CSRF_FILTER" />
    </sec:http>
    
    <sec:authentication-manager>
        <sec:authentication-provider>
            <sec:user-service>
            	<!-- ユーザー名「user」、パスワード「pass」が入力されたら
                     ログイン可能とする -->
                <sec:user name="user" password="pass" authorities="USER" />
            </sec:user-service>
        </sec:authentication-provider>
    </sec:authentication-manager>
    
    <!-- CSRFトークンのリポジトリのBean定義 -->
    <bean id="csrfTokenRepository" 
        class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository" />
    
    <!-- CSRFトークンをリクエスト毎に更新するBean定義 -->
    <bean id="chgCsrfTokenFilter" class="com.example.demo.ChgCsrfTokenFilter">
        <constructor-arg ref="csrfTokenRepository" />
    </bean>
    
    <!-- CSRFトークンのセッションキーをリクエスト毎に更新するBean定義 -->
    <bean id="updSessionCsrfFilter" class="com.example.demo.UpdSessionCsrfFilter">
        <constructor-arg ref="csrfTokenRepository" />
    </bean>

</beans>

その他の赤枠のソースは、流用ソースと同じような修正を行っている。ソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-mvc-reqtoken-errhandling/demo



なお、今回はエラー時に固定でエラー画面(error.html)に遷移するようになっているが、エラーの種類により画面遷移先を変更することもできる。その実装方法は、以下の記事を参照のこと。
https://terasolunaorg.github.io/guideline/5.4.1.RELEASE/ja/Tutorial/TutorialSecurity.html#id15

サンプルプログラムの実行結果

下記記事の「完成した画面イメージの共有」と同じ結果となる。

Spring Boot上でリクエスト毎にCSRFトークンを変える処理を複数画面を開く場合に対応してみた以前、Spring Securityを利用して、さらにリクエスト毎にCSRFトークンの値を変更するようにしたことがあったが、このプログラ...
Spring Boot上でSpring Securityのエラー処理を追加してみた今回は、Spring Securityでエラーが発生した場合に、エラー画面に遷移する処理を追加してみたので、そのサンプルプログラムを共有...

ただし、初期表示画面へのアクセスパスは、それぞれ「http://(サーバー名):(ポート番号)/(プロジェクト名)/」と読み替えること。また、一覧画面のページング処理は実装されていない。

要点まとめ

  • Spring Security用のXML定義を変更することで、エラー制御や、CSRFトークンチェックをリクエスト毎に行う対応を追加することができる。