web-dev-qa-db-fra.com

Jquery POST donnant 403 erreur interdite au printemps MVC

Je souhaite effectuer un appel ajax avec $ .POST. Mais je reçois une erreur 403. Mais GET fonctionne parfaitement bien. Mon code est:

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

Le code du contrôleur est:

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

Mais je reçois une erreur 403.

17
user3729782

Lors de l'utilisation de Spring Security avec la configuration Java, la protection CSRF est activée par défaut. Dans ce contexte, si vous envoyez une demande Ajax à un noeud final REST à l'aide de la méthode POST, vous obtiendrez une erreur manquante du jeton csrf.

Pour résoudre ce problème, il existe deux options:

Option 1: Désactiver CSRF

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

Option 2: Ajouter csrf à la demande ajax. Voir ici

65
Emiliano Schiano

Vous voudrez peut-être ajouter le jeton csrf à la demande.

L'obtention du jeton à l'aide de JSTL devrait être assez simple. Si vous utilisez Thymeleaf, voici comment vous en procurer.

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

Ensuite, ajoutez-le à votre demande:

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

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

Si tout se passe bien, la requête doit inclure quelque chose comme _ csrf: 1556bced-b323-4a23-ba1d-5d15428d29fa (le jeton csrf) et vous obtiendrez un 200 au lieu de 403.

8
izilotti

Ceci est un exemple de sans désactiver CSRF.

Étape 1: Dans votre en-tête, ajoutez CSRF comme ceci

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

Étape 2: Passer un appel avec jeton

$( "#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);
    }
  })
});
0
VK321

Si vous regardez le code source de CSRFilter, vous verrez que le filtre attend csrfToken dans l'en-tête ou le paramètre de requête . Dans ma configuration, la clé "_csrf" était la bonne clé dans le paramètre de requête . ajouté ce paramètre dans mon post call.

      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;
          });

Avec ça, ça marche pour moi.

0
BenoitJ