使用AJAX实现SpringSecurity登录(不禁用csrf )

SpringSecurity配置类代码:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WelfareSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private LoginAuthenticationFailureHandler loginAuthenticationFailureHandler;

    @Autowired
    private LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler;

    
    @Override
    protected void configure(HttpSecurity security) throws Exception {
        security.authorizeRequests()
                //放行首页
                .antMatchers("/index.jsp")
                .permitAll()
                //放行静态资源
                .antMatchers("/assets/**")
                .permitAll()
               //除此之外其他请求都需要进行授权
                .anyRequest()
                .authenticated()
                //登录请求授权
                .and()
                .formLogin()
                .loginPage("/admin/to/login.html")
                .loginProcessingUrl("/security/login.json")
                .permitAll()
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(loginAuthenticationSuccessHandler)
                .failureHandler(loginAuthenticationFailureHandler)
                //开启退出登录功能
                .and()
                .logout()
                .logoutUrl("/security/logout.json")
                .logoutSuccessUrl("/admin/to/login.html");
    }

    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
			auth.inMemoryAuthentication().
			withUser("vinci").password("lmy9901").roles("Admin");
    }

}

重写认证成功、失败处理器
其中的ResultEntity为封装的统一返回类型

@Component
public class LoginAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        ResultEntity<Object> resultEntity = ResultEntity.successWithoutData();
        String json = new Gson().toJson(resultEntity);
        httpServletResponse.setContentType("application/json;charset=utf-8");
        PrintWriter out = httpServletResponse.getWriter();
        out.write(json);
        out.flush();
        out.close();
    }

}
@Component
public class LoginAuthenticationFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        ResultEntity<Object> resultEntity = ResultEntity.failed(WelfareConstant.MESSAGE_LOGIN_FAILED);
        String json = new Gson().toJson(resultEntity);
        httpServletResponse.setContentType("application/json;charset=utf-8");
        PrintWriter out = httpServletResponse.getWriter();
        out.write(json);
        out.flush();
        out.close();
    }

}

前端页面表单:

<form class="form-horizontal" action="return false"  id="adminLoginForm">
                    <div class="form-group row">
                        <div class="col-12">
                            <input value="vinci" class="form-control" name="username" type="text" required="" placeholder="请输入账号">
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-12">
                            <input value="lmy9901" class="form-control" name="password" type="password" required="" placeholder="请输入密码">
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-12">
                            <div class="custom-control custom-checkbox">
                                <input type="checkbox" class="custom-control-input" id="customCheck1">
                                <label class="custom-control-label" for="customCheck1">记住我</label>
                            </div>
                        </div>
                    </div>

                    <div class="form-group text-center row m-t-20">
                        <div class="col-12">
                            <button id="adminLoginBtn" class="btn btn-info btn-block waves-effect waves-light" type="button">登录</button>
                        </div>
                    </div>
                </form>

注意:在head标签内一定要加入以下代码

 	<meta name="_csrf" content="${_csrf.token}" />
    <meta name="_csrf_header" content="${_csrf.headerName}" />

最后:向服务器发送AJAX请求

$(function(){

    //获取登录表单数据
    $("#adminLoginBtn").on('click', function () {
        let username = $("#adminLoginForm input[name='username']").val();
        let password = $("#adminLoginForm input[name='password']").val();
        adminLogin(username, password);
    })


})


//管理员登录方法
function adminLogin(username, password) {

    if (username == null || username == "") {
        layer.msg("请输入账号");
        return;
    }
    if (password == null || password == "") {
        layer.msg("请输入密码");
        return;
    }

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


    $.ajax({
        type: "post",
        url: "/security/login.json",
        data: {
            "username": username,
            "password": password
        },
        dataType: "json",
        beforeSend: function(request) {
            request.setRequestHeader(header, token);
        },
        success(response) {
            let result = response.operationResult;
            let msg = response.operationMessage;
            if (result == "success") {
                layer.msg("登录成功");
                setTimeout(function () {
                    window.location.href = "admin/to/main.html"
                }, 1000)
            }
            if (result == "failed") {
                layer.msg(msg);
            }
        },
        error(response) {
            layer.alert(response);
        }
    })

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security提供了防止跨站点请求伪造(CSRF)攻击的机制。在Spring Security使用CSRF可以通过以下步骤实现: 1. 在HTML表单中添加CSRF令牌。 2. 配置Spring Security以启用CSRF保护。 3. 配置CSRF令牌在表单提交时如何发送到服务器。 下面是一个基本的示例: 1. 在HTML表单中添加CSRF令牌 在表单中添加CSRF令牌可以防止攻击者向服务器发送伪造的请求。可以使用Spring Security的标签库来添加CSRF令牌。以下是一个示例: ```html <form method="post" action="/process-form"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> <!-- 其他表单元素 --> <button type="submit">Submit</button> </form> ``` 在这个例子中,我们使用了隐藏的输入字段来存储CSRF令牌,并使用Spring Security的EL表达式来生成令牌名称和值。 2. 配置Spring Security以启用CSRF保护 要启用Spring SecurityCSRF保护,需要配置一个CsrfTokenRepository。以下是一个示例: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } } ``` 在这个例子中,我们使用了CookieCsrfTokenRepository作为CsrfTokenRepository。这个仓库将生成一个CSRF令牌,并将其存储在一个cookie中,这个cookie会在每个请求中发送回服务器。 3. 配置CSRF令牌在表单提交时如何发送到服务器 当表单被提交时,需要将CSRF令牌发送回服务器。可以使用以下代码片段来从页面中的隐藏字段中提取CSRF令牌,并在表单提交时将其发送回服务器: ```javascript $(function () { var csrfToken = $("meta[name='_csrf']").attr("content"); var csrfHeader = $("meta[name='_csrf_header']").attr("content"); $(document).ajaxSend(function(e, xhr, options) { xhr.setRequestHeader(csrfHeader, csrfToken); }); }); ``` 在这个例子中,我们使用了jQuery来提取页面中的CSRF令牌,并将其作为请求头发送回服务器。 以上是一个基本的Spring Security使用CSRF的示例。如果需要更高级的配置,可以参考Spring Security的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值