spring-security AJAX POST导致405(不允许的方法)- Spring MVC

hfwmuf9z  于 2022-11-11  发布在  Spring
关注(0)|答案(3)|浏览(283)

我尝试用POST方法对我的Spring控制器/动作进行 AJAX 调用,并使用@ResponseBody从服务器返回一个对象。奇怪的是,在添加Spring安全层后,它停止工作,之前一切都工作正常。我将尝试解释我的动作来解决这个问题,然后向您展示代码/捕获/等。
1.经过一些研究,我发现一些答案告诉这个问题可能与csrf机制有关,所以我禁用了它,仍然有这个问题。(spring-security.xml below)
2.我已经做了一个wireshark捕获来检查请求/响应。我 AJAX 请求是OK的,我的控制器声明是OK的,但是我不明白为什么,405响应指示〉允许:GET(捕获波纹管)
3.我尝试通过浏览器访问我的控制器操作(例如,发出GET请求),但我收到错误HTTP状态405 -请求方法'GET'不受支持
4.我尝试将RequestMapping(method...)更改为RequestMethod.GET,请求到达控制器并正常工作,但我不希望它在GET方法上工作,我希望使用POST请求。
5.更改了RequestMapping(消费、生产、标头)以接受所有类型的数据,但仍然是405...
这是让我疯狂!我张贴我的文件波纹管,所以你可以检查它的家伙,任何提示将不胜感激。谢谢!(重要提示:这是我的绝望配置)

  • spring-security.xml文件 *
<beans:beans 
     xmlns...(all needed declarations)>

<http pattern="/js/**" security="none" />
<http pattern="/css/**" security="none" />

<!-- enable use-expressions -->
<http auto-config="true" >
    <access-denied-handler error-page="/403" />
    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
    <intercept-url pattern="/login" access="isAnonymous()" />
    <intercept-url pattern="/403" access="permitAll" />
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

    <form-login  login-page="/login"
                 username-parameter="email"
                 password-parameter="password"
                 authentication-failure-url="/login?failed" />

    <!--
    <csrf/>
    -->
</http>

 ..... (authentication)
  • 管理控制器.java*
@Controller
@RequestMapping("/admin**")
public class AdminController {

    ... (all my autowired beans)

    @RequestMapping(
        value = "/events/loadEvents",
        method = RequestMethod.POST,
        consumes = MediaType.ALL_VALUE,
        produces = MediaType.ALL_VALUE,
        headers = "Accept=*/*")
    @ResponseBody
    public Event loadEvents(@RequestParam("parentId") long parentId) {
        ... (my logic)
        return event;
    }
}

请求(Wireshark捕获)x1c 0d1x
响应(Wireshark捕获)

编辑*jquery AJAX 调用代码 *

$.ajax({
    type: 'POST',
    cache: false,
    url: /admin/events/loadEvents,
    data: { parentId: 1 },
    dataType = 'json',
    contentType = 'application/json',

    ...
});
zazmityj

zazmityj1#

经过许多小时的研究和测试,我终于得到了它,蚂蚁这是一个(非常非常)愚蠢的情况。所以,在我的问题我说
因此我禁用了它(spring-security.xml上的csrf),但问题仍然存在。
不,我没有禁用它。我是想禁用它

<!--
<csrf/>
-->

但我应该做的是:

<csrf disabled="true"/>

注解csrf标签禁用csrf,这是因为默认情况下csrf是启用的!发现这个问题后,很容易说这是一个愚蠢的错误,但当我添加csrf标签来启用它时,我认为注解它会禁用它。请在Spring文档中找到答案
现在,回到我的问题。要修复POST AJAX 调用WITH CSRF ENABLED中的405错误信息,真的很容易。我将csrf参数保存在JS变量中,如下所示:

<script type="text/javascript">
    var csrfParameter = '${_csrf.parameterName}';
    var csrfToken = '${_csrf.token}';
</script>

然后我 AJAX 调用看起来像这样:

var jsonParams = {};
jsonParams['parentId'] = 1;
jsonParams[csrfParameter] = csrfToken;
$.ajax({
    type: 'POST',
    cache: false,
    url: /admin/events/loadEvents,
    data: jsonParams,
    dataType = 'json',
    contentType = 'application/json',

    ...
});

工作起来很有魅力。希望这对将来的人有帮助。

fnx2tebb

fnx2tebb2#

$.ajaxSetup({
    dataType: "json",
    beforeSend: function(xhr, settings){
        var csrftoken = $.cookie('CSRF-TOKEN');
        xhr.setRequestHeader("X-CSRF-TOKEN", csrftoken);
    },
});
ruarlubt

ruarlubt3#

在我的情况下,同样的问题,帮助这:

  • 添加标记库:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
  • 在JSP主体中添加:
<sec:csrfMetaTags />
  • 在 AJAX 中添加
headers: {"X-CSRF-TOKEN": $("meta[name='_csrf']").attr("content")}

感谢伊利亚·舒尔金,冷静的回答,现在它在这里。

相关问题