TERASOLUNA5でSpringSecurityを使うにあたってのメモ
SpringSecurityFilterChainが原因でCSRFエラーが起きた時に調べたメモです。
以下の内容を簡単に??説明すると、
JSPで<form:form>タグを使用してリクエストを送信した場合、SpringSecurityに必要なトークンをセットして送信していて、そのトークンを送らないでリクエストするとFilterクラスでトークンがないためCSRFエラーを返すということです。
hiddenパラメータの複数追加機能
org.terasoluna.gfw.web.mvc.support.CompositeRequestDataValueProcessor
requestDataValueProcessorには本来クラスを一つしか指定できないが、TERASOLUNAが提供するCompositeRequestDataValueProcessorクラスによりリスト形式で複数hiddenパラメータを追加するクラスを指定できるようにしている。
CSRFチェック
org.springframework.security.web.reactive.result.view.CsrfRequestDataValueProcessor
hiddenパラメータに追加した項目を以下クラスのgetExtraHiddenFieldsにより取得し、チェックを行う。
二重送信チェック
org.terasoluna.gfw.web.token.transaction.TransactionTokenRequestDataValueProcessor
トランザクショントークンを、Spring MVCタグの<form:form>タグを使用してHidden領域に自動的に埋め込むためのクラス
org.springframework.web.servlet.tags.form.FormTag
Springのカスタムタグの実装をしている。
<form:form>タグを使用してフォームを送信すると、当該クラスとRequestDataValueProcessorが連携してhidden項目をJSPに定義せずに実現できる。
FormTag#writeTagContent
タグの属性を追加(書き出し)する。
FormTag#writeHiddenFields
RequestDataValueProcessorに定義したhidden項目(CSRFチェックや二重送信チェック)をタグ内にマッピングする
RESTAPIでSpringSecurityのフィルターに引っかかる場合はタグ内ので生成したトークン情報をJSP内でリクエストヘッダに追加して送信すればCSRFエラーを回避できる。
xmlhttp.setRequestHeader(“X-CSRF-TOKEN”, form1._csrf.value);
"form1"は<form:form>タグのname属性値
※関係するクラス
org.springframework.security.web.csrf.CsrfFilter
SpringSecurityFilterChainについてはこちら
https://qiita.com/opengl-8080/items/c105152c9ca48509bd0c