Spring-Security对CSRF攻击的支持

何时使用CSRF保护
        什么时候应该使用CSRF保护?我们的建议是使用CSRF保护,可以通过浏览器处理普通用户的任何请求。如果你只是创建一个非浏览器客户端使用的服务,你可能会想要禁用CSRF保护。(即所有处理来自浏览器的请求需要是CSRF保护,如果后台服务是提供API调用那么可能就要禁用CSRF保护)

配置CSRF保护

CSRF保护默认情况下使用Java配置启用

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable();//禁用CSRF保护
}
}

前提注意:SpringBoot实例中应用CSRF


The URL that triggers log out to occur (default is /logout). If CSRF protection is enabled (default), then the request must also be a POST. For more information, please consult the JavaDoc.

CSRF在SpringSecurity中默认是启动的,那么你的退出请求必须改为POST请求。这确保了注销需要CSRF令牌和一个恶意的用户不能强制注销用户

所以在SpringSecurity中需要重新配置登出

package com.niugang.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration // 里面已经包含了@Component 所以不用再上下文中在引入入了
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// spring自带的
@Autowired
private UserDetailsService userDetailsService;

/**
* configure(HttpSecurity)方法定义了哪些URL路径应该被保护
*/
@Override

protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()// 该方法所返回的对象的方法来配置请求级别的安全细节
.antMatchers("/login").permitAll() // 登录页面不拦截
.antMatchers("/api/**").permitAll() //调用api不需要拦截
.antMatchers(HttpMethod.POST, "/checkLogin").permitAll().anyRequest()
.authenticated()// 对于登录路径不进行拦截
.and().formLogin()// 配置登录页面
.loginPage("/login")// 登录页面的访问路径;
.loginProcessingUrl("/checkLogin")// 登录页面下表单提交的路径
.failureUrl("/login?paramserror=true")// 登录失败后跳转的路径,为了给客户端提示
.defaultSuccessUrl("/index")// 登录成功后默认跳转的路径;
.and().logout()// 用户退出操作
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))// 用户退出所访问的路径,需要使用Post方式
.permitAll().logoutSuccessUrl("/login?logout=true")// 退出成功所访问的路径
;
}

/**
* 忽略静态资源
*/

@Override
public void configure(WebSecurity web) throws Exception {
/*
* 在springboot中忽略静态文件路径,直接写静态文件的文件夹 springboot默认有静态文件的放置路径,如果应用spring
* security,配置忽略路径 不应该从springboot默认的静态文件开始
* 如:在本项目中,所有的js和css都放在static下,如果配置忽略路径,则不能以static开始
* 配置成web.ignoring().antMatchers("/static/*");这样是不起作用的
*/

web.ignoring().antMatchers("/themes/**", "/script/**");

}

/**
* 配置自定义用户服务
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
// .passwordEncoder(passwordEncoder());

}

/**
* 密码加密
*/
/*
* @Bean public BCryptPasswordEncoder passwordEncoder() { return new
* BCryptPasswordEncoder(); }
*/
}


HTML中需要以表单形式POST提交退出
<form action="logout" method="post">
       <input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
    <button type=‘submit‘ class=‘btn btn-warning‘ onclick="logout();">退出</button>
</form>

在登录页面输入用户名和密码,点击登录,页面报如下错误

?

这就是页面在登录时没有向后台传入后台颁发的令牌,具体代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link href="themes/bootstrap.min.css" rel="stylesheet" />
<script type="text/javascript" src="script/jquery.min.js"></script>
<!--layer弹出框-->
<link rel="stylesheet" href="script/layer/mobile/need/layer.css">
<script type="text/javascript" src="script/layer/layer.js"></script>
</head>
<!-- -->
<style>
form {
width: 60%;
margin: 0 auto;
}
</style>
<body>
<form action="checkLogin" method=‘post‘>
<h2 style="text-align: center">spring boot</h2>
<div class="form-group">
<label for="name">姓名</label> <input type="text" class="form-control"
name="username" placeholder="姓名">
</div>
<div class="form-group">
<label for="password">密码</label> <input type="password"
class="form-control" name="password" placeholder="密码">
</div>
         <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<button type="submit" id="btn_save"
class="btn btn-primary form-control">保存</button>
</form>

<script type="text/javascript">
   <#if errorMessage??>
layer.msg(‘${errorMessage}‘, {icon: 4,time:1000,anim: 6});

   </#if>

</script>
</body>
</html>

这样才能登录成功

对于Ajax和JSON的异步请求

<head>
<meta charset="UTF-8">
<meta name="_csrf" content="${_csrf.token}" />
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}" />
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="themes/bootstrap.min.css" />
<script type="text/javascript" src="script/jquery.min.js"></script>
<script type="text/javascript" src="script/bootstrap.js"></script>
<!--layer弹出框-->
<link rel="stylesheet" href="script/layer/mobile/need/layer.css">
<script type="text/javascript" src="script/layer/layer.js"></script>
<style type="text/css">
button {
margin-left: 15px;
}
</style>
</head>

每次在提交请求之前先设置header里面的token,这样才能正常运行

var token = $("meta[name=‘_csrf‘]").attr("content");
var header = $("meta[name=‘_csrf_header‘]").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});

用户想要坚持CSRF Token在cookie中。 默认情况下CookieCsrfTokenRepository将编写一个名为 XSRF-TOKEN的cookie和从头部命名 X-XSRF-TOKEN中读取或HTTP参数 _csrf。

//代码如下:

.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())

?

示例显式地设置cookieHttpOnly=false. 这是必要的,允许JavaScript(例如AngularJS)读取它。 如果你不需要使用JavaScript直接读取cookie的能力,建议省略 cookieHttpOnly=false (通过使用new CookieCsrfTokenRepository()代替) 提高安全性.


The URL that triggers log out to occur (default is /logout). If CSRF protection is enabled (default), then the request must also be a POST. For more information, please consult the JavaDoc.

       微信公众号: 

?

JAVA程序猿成长之路

分享资源,记录程序猿成长点滴。专注于Java,Spring,SpringBoot,SpringCloud,分布式,微服务

原文地址:https://www.cnblogs.com/niugang0920/p/12195976.html

时间: 2024-10-31 05:34:26

Spring-Security对CSRF攻击的支持的相关文章

spring security login csrf 失效问题

如果要使用csrf,login 页面不能定义为 <http security="none" pattern="/user/login.*" /> 因为所有过滤器都不起作用了,包括 csrf 过滤器 要定义为:access="permitAll" <http> <intercept-url pattern="/user/**" access="permitAll" /> &

Spring security csrf实现前端纯html+ajax

spring security集成csrf进行post等请求时,为了防止csrf攻击,需要获取token才能访问 因此需要添加 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 动态获取token 这样的话,需要使用jsp或模板引擎 但又想使用纯html+ajax.很难受 最近想到了一个办法 通过ajax获取token,后端仍使用js

Spring Security 学习总结(2) 持续更新中

从一个最简单的Spring Security Java Configuration 看起 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {     @Autowired     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {    

spring security源码分析之二---web包分析

Spring 是一个非常流行和成功的 Java 应用开发框架.Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案.一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分.用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.用户认证一般要求用户提供用户名和密码.系统通过校验用户名和密码来完成认证过程.用户授权指的是验证某个用户是否有权限执行某个操作.在一

Spring Security学习总结

1.Spring Security介绍  一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分. 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.用户认证一般要求用户提供用户名和密码.系统通过校验用户名和密码来完成认证过程. 用户授权指的是验证某个用户是否有权限执行某个操作.在一个系统中,不同用户所具有的权限是不同的.比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改.一般来说,系统

Spring security 3 非常全的文档 API 中文版

Spring Security 安全权限管理手册 序言 I. 基础篇 6.1. MD5加密 6.2. 盐值加密 6.3. 用户信息缓存 6.4. 获取当前用户信息 5.1. 数据库表结构 5.2. 初始化数据 5.3. 实现从数据库中读取资源信息 5.3.1. 需要何种数据格式 5.3.2. 替换原有功能的切入点 4.1. 实现自定义登陆页面 4.2. 修改配置文件 4.3. 登陆页面中的参数配置 4.4. 测试一下 3.1. 自定义表结构 3.2. 初始化数据 3.3. 获得自定义用户权限信息

(一)关于spring security的简要介绍以及相关配置和jar包认识

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作. 安全主要包括两个操作,"认证和验证(权限控制)"

springboot集成spring security实现restful风格的登录认证 附代码

一.文章简介 本文简要介绍了spring security的基本原理和实现,并基于springboot整合了spring security实现了基于数据库管理的用户的登录和登出,登录过程实现了验证码的校验功能. 完整代码地址:https://github.com/Dreamshf/spring-security.git 二.spring security框架简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.主要包括:用户认证

Spring Security 从配置入门 学习讲解。万恶之源------------web.xml

这段时间,工作闲了下来,接触了Spring Security,对于我一个基础很差的人来说,无疑是个挑战啊. 经过一段时间的摸索,终于有了点眉目,在这里,要特别感谢http://blog.csdn.net/u012367513/article/details/38866465 二当家的 博文对我的帮助.我的代码也是在他的基础上整理而来,只是增加了自己的一些见解. 再次感谢他的帮助. 我的基础很是薄弱,最然 二当家的 博文中已经讲解的很是清楚,但是我还是希望自己能过上一遍. 本文适宜读者: Spri