当前位置: 首页 > 知识库问答 >
问题:

CSRF/Spring Security-通过AJAX登录后出现403错误

梅宏盛
2023-03-14

在Spring Security 5.1.4中使用CSRF保护时,我遇到了一个问题。

我已经为应用程序设置了自定义登录页面。当用户输入其凭据时,会发出AJAX请求。成功处理程序执行其职责并在响应中返回JSON文档。当AJAX调用成功时,屏幕会动态更新,方法是删除用户名和密码字段,并将其替换为下拉字段和继续按钮。

当用户从下拉列表中进行选择并单击“继续”按钮时,表单上的操作将更改,并使用POST方法提交表单。然后将用户引导到主屏幕。不幸的是,应用程序以一个禁止的(403)错误响应。

当我修改WebSecurityConfigureAdapter以禁用CSRF保护时,我的登录屏幕将按预期执行。

我提交表格时是否遗漏了什么?注意,我已经在form元素的一个隐藏字段中包含了CSRF参数和标记。

网络安全配置

protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/css/**", "/images/**", "/js/**")
                .permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .successHandler(customAuthenticationHandler)
                .permitAll()
                .and()
                .logout()
                .invalidateHttpSession(true)
                .deleteCookies("JESSIONID")
                .permitAll();
    }

public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
}

控制器

@RequestMapping(value = "/login", method = RequestMethod.GET)
public String logIn() {
    return "login-custom";
}

@RequestMapping(value = "/home", method = RequestMethod.POST)
public String home() {
    return "home";
}

JSP

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title></title>

    <script type="text/javascript" src="/workdaybsa/js/jquery-1.10.2.min.js"></script>
    <script language="javascript">

        function login() {
            $.ajax({
                url: $('#loginForm').attr('action'),
                type: 'POST',
                data: $('#loginForm').serialize(),
                dataType: "json",
                success: function(response){
                    $('#loginSection').attr('style', 'display:none');
                    $('#selectionSection').removeAttr('style');
                },
                error: function (xhr, status, error) {
                    alert(status);
                    alert(error);
                }
           });
        }

        function proceed() {
            $('form').attr('action', 'home');
            $('form').submit();
        }
    </script>

</head>

<body>

    <form id="loginForm" action="login" method="post">

        <div id="loginSection">
            <p>
                <label for="username">Username</label>
                <input type="text" id="username" name="username">
            </p>
            <p>
                <label for="password">Password</label>
                <input type="password" id="password" name="password">
            </p>
            <input type="button" value="Sign In" onclick="login()">
        </div>
        <div id="selectionSection" style="display:none">
            <select id="selection">
                <option value="">-- Select The Option --</option>
            </select>
            <input type="button" value="Continue" onclick="proceed()">
        </div>
        <input type="hidden" id="csrf" name="${_csrf.parameterName}" value="${_csrf.token}"/>

    </form>

</body>

</html>

共有1个答案

上官景铄
2023-03-14

CSRF token是一种防伪令牌,您需要在每次请求时使用CSRF token头属性将其传递回Spring Security,尽管它位于隐藏的输入字段中,但ajax调用中并未包含该属性。这就是CSRF验证失败并抛出403的原因。

在这个SO问题中提供了解决方案

要无耻地复制粘贴答案,这就是你需要的:

$.ajax({
  url: route.url,
  ...
  headers: {
    'Csrf-Token': $('#csrf").val()
  }
});
 类似资料:
  • 我将使用CSRF codeigniter和ajax进行安全登录。但是我有一个问题,我的语法。 这是我的表格: 这是我的javascript: 和我的控制器: 我的模型是:

  • 问题内容: 每当我尝试从数据库中获取用户信息时,都会收到-error 消息。关于下面的代码,每当我尝试通过按Ajax测试按钮尝试请求时,它都无法运行并给我发出警报,但是在控制台中也给我一个-error。我不确定是否与Spring安全性有关? 用户JSP页面: 用户控制器类: 问题答案: 它通常是由Spring默认的CSRF保护引起的。 例如,如果你使用JS代码中的DELETE HTTP请求,则还需

  • 问题内容: 我试图通过从slide_images文件夹中获取所有图像名称并将其附加到来动态地动态显示滑块图像。 问题答案: 最后,我通过使用json解决了这个问题。 首先,我创建getimages.php文件并读取该文件中的目录,并获取所有图像名称并将该名称存储在数组中。 getimages.php 从要动态加载图像的页面调用getimages.php。 index.php 这对我来说是完美的。

  • 问题内容: 我已经在SO上看到了很多,但是没有什么可以解决我的问题。 问题: 启用CSRF中间件后,Django在AJAX表单请求中回复403,并指出: “未设置CSRF cookie。” 根据文档,实现了JS功能,该功能设置了自定义 “ X-CSRFToken” 标头。 它按预期工作,从浏览器获取 “ csrftoken” cookie并将其与AJAX请求一起发布: 但是响应仍然是403。 尝试

  • 我在一个网站上工作,跟踪待办事项列表,并从服务器上提取它。下面有两个示例ajax调用。任务GET调用工作正常,但添加POST不工作。出于某种原因,它给我一个403禁止的错误,结果,不执行代码。 在Django框架中发出ajax Post请求时,我看到了403禁止的错误,我阅读了@yohn发布的链接,但我不理解如何实现这个解决方案。

  • 我正在尝试为wordpress开发一个登录ajax表单。这个插件似乎工作得很好。如果我插入了正确的用户名和密码,登录将正常工作并显示正确的消息,然后重定向到正确的页面,但是如果我插入了错误的用户名和密码值,则不会发生任何情况,错误消息也不会出现。 似乎该函数是_wp_error,不回显该错误。 你知道为什么吗?低于我的代码 感谢在adv. PHP 超文本标记语言 JS