リクエストパラメータ「_csrf」またはヘッダー「X-CSRF-TOKEN」で無効なCSRFトークン「null」が見つかりました


90

Spring Security 3.2を構成した後_csrf.tokenは、リクエストまたはセッションオブジェクトにバインドされません。

これは春のセキュリティ設定です:

<http pattern="/login.jsp" security="none"/>

<http>
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <form-login login-page="/login.jsp"
                authentication-failure-url="/login.jsp?error=1"
                default-target-url="/index.jsp"/>
    <logout/>
    <csrf />
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="test" password="test" authorities="ROLE_USER/>
        </user-service>
    </authentication-provider>
</authentication-manager>

login.jspファイル

<form name="f" action="${contextPath}/j_spring_security_check" method="post" >
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
    <button id="ingresarButton"
            name="submit"
            type="submit"
            class="right"
            style="margin-right: 10px;">Ingresar</button>
    <span>
        <label for="usuario">Usuario :</label>
        <input type="text" name="j_username" id="u" class="" value=''/>
    </span>
    <span>
        <label for="clave">Contrase&ntilde;a :</label>

        <input type="password"
               name="j_password"
               id="p"
               class=""
               onfocus="vc_psfocus = 1;"
               value="">
    </span>
</form>

そして、次のHTMLをレンダリングします。

<input type="hidden" name="" value="" />

結果は403 HTTPステータスです。

Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

更新 デバッグの後で、リクエストオブジェクトはDelegatingFilterProxyから細かく取得されますが、CoyoteAdapterの469行目でrequest.recycle();を実行します。すべての属性を消去します...

Tomcat 6.0.36、7.0.50、JDK 1.7でテストします。

私はこの動作を理解していません。むしろ、誰かが私に、CSRFで動作するSpring Security 3.2でのアプリケーションサンプル戦争の方向を教えてくれる可能性があります。


1
どのSpringバージョンを使用していますか?これと同じことは、spring-security.xmlSpring 4.0.0 RELEASE(GA)、Spring Security 3.2.0 RELEASE(GA)(Struts 2.3.16と統合されていますが)では機能します(ただし、には違いがあります)。 Spring MVCのみで試してください)。ただし、リクエストがステータス403のファイルをアップロードするマルチパートの場合は失敗します。解決策を見つけるのに苦労しています。
小さな

Spring 3.2.6、Spring Security 3.2.0、CSRF、トークンがhttp-requestオブジェクトに追加されました。セッションオブジェクトはリクエストスレッドと同じですが、レンダリングされるまでjspがすべての属性を削除します。属性を残す... filter_applied
Hugo Robayo 14

@Tiny:マルチパート問題の解決策を見つけましたか?私はまったく同じ問題を抱えています。
Rob Johansen、2014

1
@AlienBishop:はい、この回答を確認してください(SpringとStrutsの組み合わせを使用しています)。Spring MVCを単独で使用している場合は、この回答を確認してください。フィルターの順序web.xmlは非常に重要です。MultipartFilterの前に宣言する必要がありますspringSecurityFilterChain。お役に立てば幸いです。ありがとう。
小さな

回答:


110

SpringアプリケーションのCSRF(Cross Site Request Forgery)保護が有効になっているようです。実際にはデフォルトで有効になっています。

spring.ioによると:

いつCSRF保護を使用する必要がありますか?私たちの推奨は、通常のユーザーがブラウザで処理できるすべてのリクエストに対してCSRF保護を使用することです。ブラウザー以外のクライアントで使用されるサービスのみを作成する場合は、CSRF保護を無効にすることをお勧めします。

それを無効にするには:

@Configuration
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
  }
}

CSRF保護を有効にしたままにする場合は、フォームにを含める必要がありますcsrftoken。あなたはこのようにそれを行うことができます:

<form .... >
  ....other fields here....
  <input type="hidden"  name="${_csrf.parameterName}"   value="${_csrf.token}"/>
</form>

フォームのアクションにCSRFトークンを含めることもできます。

<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">

2
これは何をすべきかだけでなく、これらのエラーを停止するために何かをする前に考慮すべきことも説明しているので、答えとして受け入れられるべきです。
トーマスカーライル

1
次のこともできます.csrf().ignoringAntMatchers("/h2-console/**")
insan-e

上記の回答では、クエリパラメータスタイルを経由しないでください。これを行うと、トークンが公開されます。
Pramod S. Nikam

31

ログインフォームに追加しないでください。;

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

Springセキュリティドキュメントのここで述べられているように


12

適用するsecurity="none"場合、csrfトークンは生成されません。ページはセキュリティフィルターを通過しません。ANONYMOUSロールを使用します。

詳細には行きませんでしたが、うまくいきました。

 <http auto-config="true" use-expressions="true">
   <intercept-url pattern="/login.jsp" access="hasRole('ANONYMOUS')" />
   <!-- you configuration -->
   </http>

私はsecurity = noneを使用していて、あなたの答えに移動してこの問題を解決しました。それは素晴らしいですthymeleafはcsrfトークンを自動的に追加します。よろしくお願いします!
rxx


7

thymeleafを使用すると、以下を追加できます。

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

6

csrfを無効にするSpringドキュメント:https ://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-configure

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
      http.csrf().disable();
   }
}

既存の回答をコピーしないでください。
james.garriss 2017

4

以前は同じ問題がありました。

設定でsecurity = "none"を使用しているため、_csrfを生成できません:

<http pattern="/login.jsp" security="none"/>

上記の設定を置き換える/login.jspページのaccess = "IS_AUTHENTICATED_ANONYMOUSLY"を設定できます。

<http>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <form-login login-page="/login.jsp"
            authentication-failure-url="/login.jsp?error=1"
            default-target-url="/index.jsp"/>
    <logout/>
    <csrf />
</http>


1

Githubで実際に動作するサンプルアプリケーションを確認し、セットアップと比較してください。


私はSpring 3.2.6にダウングレードします。SpringMVCがなくても動作することを願っています。
Hugo Robayo 2014

はい、Spring 3.1.4にあった既存のアプリケーションからサンプルアプリケーションを作成したので、問題なく動作するはずです。
マニッシュ2014

ハハハハハハ、素晴らしい、それを機能させるだけではダウングレードは解決策ではないbhaiya ji @manish
Kuldeep Singh

1

どちらの解決策も私には役立たなかった。春の形で私のために働いた唯一のものは:

action = "./ upload?$ {_ csrf.parameterName} = $ {_ csrf.token}"

交換された:

action = "./ upload?_csrf = $ {_ csrf.token}"

(Java構成でcsrfを有効にしたSpring 5)


0

コントローラーに以下を追加します。

@RequestParam(value = "_csrf", required = false) String csrf

そしてJSPページに追加

<form:form modelAttribute="someName" action="someURI?${_csrf.parameterName}=${_csrf.token}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.