web-dev-qa-db-ja.com

Jquery POST spring mvcで403禁止エラーが発生する

$ .POSTを使用してajax呼び出しを行いたい。しかし、403エラーが発生しています。ただし、GETは完全に正常に機能します。私のコードは:

var url = "/xyz/abc/subscribe?name="+name;
$.post(url, function(data){
    alert(data);
});

コントローラコードは次のとおりです。

@RequestMapping(value = "/xyz/abc/subscribe", method = RequestMethod.POST)
public @ResponseBody
    String subscribe(@RequestParam("name") String name)
        throws Exception {
    String message = "TESTING";
    return message;
}

しかし、403エラーが発生します。

20
user3729782

Spring SecurityをJava構成で使用すると、CSRF保護がデフォルトで有効になります。このコンテキストでは、RESTメソッドを使用してPOSTエンドポイントにAjaxリクエストを行うと、csrfトークンが見つからないというエラーが発生します。

これを解決するには、2つのオプションがあります。

オプション1:csrfを無効にする

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

オプション2:csrfをajaxリクエストに追加します。 こちら をご覧ください

79

要求にcsrfトークンを追加することもできます。

JSTLを使用してトークンを取得するのは非常に簡単です。 Thymeleafを使用している場合は、次の方法で入手できます。

<script th:inline="javascript">
    /*<![CDATA[*/
    var _csrf_token = /*[[${_csrf.token}]]*/ '';
    var _csrf_param_name = /*[[${_csrf.parameterName}]]*/ '';
    /*]]>*/
</script>

次に、リクエストに追加します。

var requestData = {
    'paramA': paramA,
    'paramB': paramB,
};
requestData[_csrf_param_name] = _csrf_token; // Adds the token

$.ajax({
    type: 'POST',
    url: '...your url...',
    data: requestData,
    ...
});

すべてがうまくいけば、リクエストには_csrf:1556bced-b323-4a23-ba1d-5d15428d29fa(csrfトークン)のようなものを含める必要があり、403ではなく200を取得します。

8
izilotti

これは、CSRFを無効にしない例です。

ステップ1:ヘッダーに次のようにCSRFを追加します

<meta th:name="${_csrf.parameterName}" th:content="${_csrf.token}"/>

ステップ2:トークンを使用して電話をかける

$( "#create_something" ).click(function() {

  var token = $("meta[name='_csrf']").attr("content");

  $.ajax({
    url : '/xxxxxxxxxxxx', // url to make request
    headers: {"X-CSRF-TOKEN": token}, //send CSRF token in header
    type : 'POST',
    success : function(result) {
        alert(result);
    }
  })
});
4
VK321

CSRFilterソースコードを見ると、フィルターがヘッダーまたはクエリパラメーターでcsrfTokenを待機していることがわかります。私の構成では、キー「_csrf」はクエリパラメータの正しいキーでした。そこで、このパラメータをポストコールに追加しました。

      var csrfCookie = getCsrfCookie();
                alert(csrfCookie);
                
        function getCsrfCookie()
        {
                var ret = "";
                var tab = document.cookie.split(";");
                
                if(tab.length>0){
                        var tab1 = tab[0].split("=");
                        if(tab1.length>1)
                        {
                                ret =tab1[1];
                        }
                }
                return ret;
        }
        
        $http.post('/testPost?_csrf='+csrfCookie).success(function (response) {
             alert("post : "+response);
              return response;
          });

これで、私にとってはうまくいきます。

0
BenoitJ