【问题标题】:Jquery POST giving 403 forbidden error in spring mvcJquery POST在spring mvc中给出403禁止错误
【发布时间】:2014-09-29 08:27:25
【问题描述】:

我想使用 $.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 错误。

【问题讨论】:

  • 你的应用服务器日志有错误吗?
  • 不...我没有发现任何错误。
  • 我正在登录日志:org.springframework.security.access.AccessDeniedException:访问被拒绝
  • 403 表示服务器可以正确验证用户,但用户没有执行所选操作的适当权限。你在使用 Spring 安全性吗?如果有,贴出相关配置
  • 我有类似的错误,但仍然没有解决stackoverflow.com/questions/25800657/…

标签: jquery spring-mvc post http-status-code-403


【解决方案1】:

使用带有 Java 配置的 Spring Security,默认情况下启用 CSRF 保护。 在这种情况下,如果您使用 POST 方法向 REST 端点发出 Ajax 请求,您将收到 csrf token missing 错误。

要解决这个问题,有两种选择:

选项 1: 禁用 csrf

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

选项 2: 将 csrf 添加到 ajax 请求中。见here

【讨论】:

  • @Override of configure 假设您的控制器是 what 类型/类的子类?
  • org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter 的子类
  • 这点你一定知道:- 16.3 什么时候使用CSRF 保护 什么时候应该使用CSRF 保护?我们的建议是对普通用户可以通过浏览器处理的任何请求使用 CSRF 保护。如果您只创建非浏览器客户端使用的服务,您可能希望禁用 CSRF 保护。 SRC:docs.spring.io/spring-security/site/docs/current/reference/html/…
  • 看看这个:stackoverflow.com/questions/27834867/… 了解如何通过 jquery-ajax 放置 csrf 令牌。
  • 值得强调的是,不推荐使用选项 1,因为它可能有风险。
【解决方案2】:

您可能希望将 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 令牌),您将获得 200 而不是 403。

【讨论】:

    【解决方案3】:

    这是一个不禁用 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】:

      如果您查看 CSRFilter 源代码,您会看到过滤器正在等待标头或查询参数上的 csrfToken。 在我的配置中,键“_csrf”是查询参数中的正确键。 所以,我在我的 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;
                });

      有了这个,它对我有用。

      【讨论】:

        【解决方案5】:

        您正在尝试向您无权访问的 REST 端点发出 POST 请求。您的会话已失效,或者您登录的用户没有@geoand 已经指出的权限。

        【讨论】:

          猜你喜欢
          • 2021-09-04
          • 1970-01-01
          • 2017-08-11
          • 1970-01-01
          • 2013-08-29
          • 1970-01-01
          • 2018-10-31
          • 1970-01-01
          • 2017-03-12
          相关资源
          最近更新 更多