0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Terasolunaの二重送信防止とSpring Securityのcsrf対策を両立させる方法

Last updated at Posted at 2019-09-29

はじめに

この組み合わせで問題が起きて解決したメモです。

Terasolunaの二重送信防止ページについては以下をご覧ください

環境

Adopt Open JDK Hotspot 11.0.3
Spring boot 2.1.0M4

pom.xml

二重送信防止機能についてはTerasolunaの機能を使いますので、Dependencyに追加します。
terasoluna-gfw-commonはいらない気もしますが、なんとなく入っています。

pom.xml
        <dependency>
            <groupId>org.terasoluna.gfw</groupId>
            <artifactId>terasoluna-gfw-common</artifactId>
            <version>5.5.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.terasoluna.gfw</groupId>
            <artifactId>terasoluna-gfw-web</artifactId>
            <version>5.5.1.RELEASE</version>
        </dependency>

InterceptorとRequestDataValueProcessorの設定

Terasolunaの二重送信防止機能はInterceptorでRequestにAttributeを設定して、それをキーにRequestDataValueProcessorでhiddenを作りだすみたいな動きをします。
そのため、Interceptorの設定とhiddenを作ってくれるRequestDataValueProcessorの設定を行います。

ここで注意点があり、Spring Securityを使用するとcsrf対策のためのhiddenを埋め込む設定であるCsrfRequestDataValueProcessorが自動的にBean登録されます。
このProcessorは全体で1つしか登録出来ないため、特に何もしなければcsrf対策か二重送信防止かどちらかしか使うことが出来ません。
そこで、Terasoluna内にあるCompositeRequestDataValueProcessorという複数のRequestDataValueProcessorを使用するためのクラスをBean登録することで両立させることになります。

また、今回は例なので、HandlerInterceptorを全てのURLに設定していますが、必要に応じてexcludePathPatternsで除外条件を作ってあげてください。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.support.RequestDataValueProcessor;
import org.terasoluna.gfw.web.mvc.support.CompositeRequestDataValueProcessor;
import org.terasoluna.gfw.web.token.transaction.TransactionTokenInterceptor;
import org.terasoluna.gfw.web.token.transaction.TransactionTokenRequestDataValueProcessor;

@Configuration
public class WebMcvConfig implements WebMvcConfigurer {

    @Bean
    public TransactionTokenInterceptor transactionTokenInterceptor() {
        return new TransactionTokenInterceptor();
    }

    @Bean
    public RequestDataValueProcessor requestDataValueProcessor() {
        return new CompositeRequestDataValueProcessor(new CsrfRequestDataValueProcessor(), new TransactionTokenRequestDataValueProcessor());
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(transactionTokenInterceptor()).addPathPatterns("/**");
    }
}

Beanの上書きを許容する

Beanはデフォルトだと上書き出来ないように設定されているため、設定で上書き出来るように許容してあげます。
この設定を行わないとBean重複してるとしてエラーとなってしまいます。

ただし、この設定を入れると上書き出来てしまうため、Bean関連の設定がしっかりしていないと思わぬ挙動が発生してしまいます。ご注意ください。

spring:
  main:
    allow-bean-definition-overriding: true

おわりに

なんでSpringに二重送信防止機能がデフォルトで入っていないのでしょうか。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?