【Spring-Security】Re09 CSFR处理
一、CSRF:
CSRF 全称 Cross Site Request Forgery 跨站请求伪造
又称为OneClick Attack & SessionRiding
是非法请求访问,通过伪造用户请求访问受信任网站
什么是跨域?
只要 协议 - IP地址 - 端口号 三者中的任何一个不相同进行的访问,就是跨域请求
相关资料:
https://blog.csdn.net/xiaoxinshuaiga/article/details/80766369
二、Security的CSRF设置:
Security4版本开始默认开启CSRF攻击拦截,验证的方法是要求凭证提供键为 _csrf 的ID
该Token在服务端生成,登录时会用户携带此ID一并给Security。
演示案例:
首先取消CSRF关闭:
package cn.zeal4j.configuration; import cn.zeal4j.handler.CustomAccessDeniedHandler;
import cn.zeal4j.handler.FarsAuthenticationFailureHandler;
import cn.zeal4j.handler.FarsAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.parameters.P;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import javax.sql.DataSource; /**
* @author Administrator
* @file IntelliJ IDEA Spring-Security-Tutorial
* @create 2020 09 27 21:55
*/
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired
private AccessDeniedHandler accessDeniedHandler;
@Qualifier("userDetailsServiceImpl")
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private DataSource dataSource;
@Autowired
private PersistentTokenRepository persistentTokenRepository; @Bean
public PersistentTokenRepository getPersistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource); // 数据源注入
jdbcTokenRepository.setCreateTableOnStartup(false); // 由Security完成Token表的创建,如果有了就设置false关闭
return jdbcTokenRepository;
} @Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
} @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.formLogin(). // 设置登陆行为方式为表单登陆
// 登陆请求参数设置
usernameParameter("username").
passwordParameter("password"). loginPage("/login.html"). // 设置登陆页面URL路径
loginProcessingUrl("/login.action"). // 设置表单提交URL路径 successForwardUrl("/main.page"). // 设置认证成功跳转URL路径 POST请求
failureForwardUrl("/error.page"); // 设置认证失败跳转URL路径 POST请求 // successHandler(new FarsAuthenticationSuccessHandler("https://www.acfun.cn/")). // 使用自定义的重定向登陆
// failureHandler(new FarsAuthenticationFailureHandler("/error.html")).; // 跨域处理,不需要跳转了 httpSecurity.authorizeRequests().
regexMatchers(HttpMethod.POST, "正则表达式").permitAll(). // 还可以对符合正则表达式的请求方式进行要求,这个属性使用来制定请求的方式 antMatchers("/**/*.js", "/**/*.css", "/**/images/*.*").permitAll(). // 静态资源放行 antMatchers("/login.html").permitAll(). // 登陆页面允许任意访问
antMatchers("/error.html").permitAll(). // 失败跳转后重定向的页面也需要被允许访问
antMatchers("/admin.page").hasAnyAuthority("admin"). /*antMatchers("/vip-01.page").hasAnyAuthority("vip-01").*/
antMatchers("/vip-01.page").hasRole("vip-01").
antMatchers("/ip.page").hasIpAddress("192.168.43.180"). // mvcMatchers("/main.page").servletPath("/xxx").permitAll(). // mvcMatchers资源放行匹配
// antMatchers("/xxx/main.page").permitAll(). // 或者多写MSP的前缀 anyRequest().authenticated(); // 其他请求均需要被授权访问
// anyRequest().access("@customServiceImpl.hasPermission(request, authentication)"); // 自定义Access配置 // CSRF攻击拦截关闭
// httpSecurity.csrf().disable(); httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 记住我
httpSecurity.rememberMe().
tokenValiditySeconds(60). // 设置Token有效时间, 以秒为单位取值
userDetailsService(userDetailsService).
tokenRepository(persistentTokenRepository); // 退出登录处理
httpSecurity.
logout().
// logoutUrl("/xxx/xxx/logout").
logoutSuccessUrl("/login.html");
}
}
注意CSRF的Token需要Thymeleaf模板获取,也就是登录页面要放在模板目录里面,这里就重新编写一个登陆页面【csrf-login.html】
在登陆页面设置CSRF的Token处理:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
h3,p {
text-align: center;
}
</style>
</head>
<body>
<h3>custom login page</h3>
<form method="post"th:action="@{/login.action}" >
<input type="hidden" th:value="${_csrf.token}" name="_csrf" th:if="${_csrf}" >
<p>username: <input type="text" name="username"></p>
<p>password: <input type="password" name="password"></p>
<p>rememberMe: <input type="checkbox" name="remember-me" value="true"></p>
<p><input type="submit" value="login"></p>
</form>
</body>
</html>
编写控制器
package cn.zeal4j.controller; import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; /**
* @author Administrator
* @file IntelliJ IDEA Spring-Security-Tutorial
* @create 2020 09 27 22:35
*/
@Secured("ROLE_vip-01")
@Controller
public class LoginController { @PostMapping("csrf-login.page")
public String toCsrfLoginPage() {
return "csrf-login";
} @RequestMapping("main.page")
public String toMainPage() {
return "main"; // 模版内的页面不允许重定向,忘了忘了
} @PostMapping("error.page") // 控制器不支持POST请求跳转解析, 需要控制器跳转 Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
public String redirectToErrorPage() {
return "redirect:/error.html"; // 重定向要写/标识 区分模版解析
} }
配置再更改为这个控制接口:
package cn.zeal4j.configuration; import cn.zeal4j.handler.CustomAccessDeniedHandler;
import cn.zeal4j.handler.FarsAuthenticationFailureHandler;
import cn.zeal4j.handler.FarsAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.parameters.P;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import javax.sql.DataSource; /**
* @author Administrator
* @file IntelliJ IDEA Spring-Security-Tutorial
* @create 2020 09 27 21:55
*/
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired
private AccessDeniedHandler accessDeniedHandler;
@Qualifier("userDetailsServiceImpl")
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private DataSource dataSource;
@Autowired
private PersistentTokenRepository persistentTokenRepository; @Bean
public PersistentTokenRepository getPersistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource); // 数据源注入
jdbcTokenRepository.setCreateTableOnStartup(false); // 由Security完成Token表的创建,如果有了就设置false关闭
return jdbcTokenRepository;
} @Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
} @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.formLogin(). // 设置登陆行为方式为表单登陆
// 登陆请求参数设置
usernameParameter("username").
passwordParameter("password"). // loginPage("/login.html"). // 设置登陆页面URL路径
loginPage("/csrf-login.page").
loginProcessingUrl("/login.action"). // 设置表单提交URL路径 successForwardUrl("/main.page"). // 设置认证成功跳转URL路径 POST请求
failureForwardUrl("/error.page"); // 设置认证失败跳转URL路径 POST请求 // successHandler(new FarsAuthenticationSuccessHandler("https://www.acfun.cn/")). // 使用自定义的重定向登陆
// failureHandler(new FarsAuthenticationFailureHandler("/error.html")).; // 跨域处理,不需要跳转了 httpSecurity.authorizeRequests().
regexMatchers(HttpMethod.POST, "正则表达式").permitAll(). // 还可以对符合正则表达式的请求方式进行要求,这个属性使用来制定请求的方式 antMatchers("/**/*.js", "/**/*.css", "/**/images/*.*").permitAll(). // 静态资源放行
antMatchers("/csrf-login.page").permitAll().
antMatchers("/login.html").permitAll(). // 登陆页面允许任意访问
antMatchers("/error.html").permitAll(). // 失败跳转后重定向的页面也需要被允许访问
antMatchers("/admin.page").hasAnyAuthority("admin"). /*antMatchers("/vip-01.page").hasAnyAuthority("vip-01").*/
antMatchers("/vip-01.page").hasRole("vip-01").
antMatchers("/ip.page").hasIpAddress("192.168.43.180"). // mvcMatchers("/main.page").servletPath("/xxx").permitAll(). // mvcMatchers资源放行匹配
// antMatchers("/xxx/main.page").permitAll(). // 或者多写MSP的前缀 anyRequest().authenticated(); // 其他请求均需要被授权访问
// anyRequest().access("@customServiceImpl.hasPermission(request, authentication)"); // 自定义Access配置 // CSRF攻击拦截关闭
// httpSecurity.csrf().disable(); httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 记住我
httpSecurity.rememberMe().
tokenValiditySeconds(60). // 设置Token有效时间, 以秒为单位取值
userDetailsService(userDetailsService).
tokenRepository(persistentTokenRepository); // 退出登录处理
httpSecurity.
logout().
// logoutUrl("/xxx/xxx/logout").
logoutSuccessUrl("/login.html");
}
}
使用csrf登录:
CSRF的显示在这里:

【Spring-Security】Re09 CSFR处理的更多相关文章
- Spring Security OAuth2 开发指南
官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...
- spring mvc 和spring security配置 web.xml设置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmln ...
- SPRING SECURITY JAVA配置:Web Security
在前一篇,我已经介绍了Spring Security Java配置,也概括的介绍了一下这个项目方方面面.在这篇文章中,我们来看一看一个简单的基于web security配置的例子.之后我们再来作更多的 ...
- 【OAuth2.0】Spring Security OAuth2.0篇之初识
不吐不快 因为项目需求开始接触OAuth2.0授权协议.断断续续接触了有两周左右的时间.不得不吐槽的,依然是自己的学习习惯问题,总是着急想了解一切,习惯性地钻牛角尖去理解小的细节,而不是从宏观上去掌握 ...
- spring security oauth2.0 实现
oauth应该属于security的一部分.关于oauth的的相关知识可以查看阮一峰的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html ...
- Spring Security(08)——intercept-url配置
http://elim.iteye.com/blog/2161056 Spring Security(08)--intercept-url配置 博客分类: spring Security Spring ...
- Spring Security控制权限
Spring Security控制权限 1,配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了. < ...
- Spring Security笔记:Hello World
本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(比如:../welcome) 注:以下内 ...
- Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken
在前面的学习中,配置文件中的<http>...</http>都是采用的auto-config="true"这种自动配置模式,根据Spring Securit ...
- spring session 和 spring security整合
背景: 我要做的系统前面放置zuul. 使用自己公司提供的单点登录服务.后面的业务应用也是spring boot支撑的rest服务. 目标: 使用spring security管理权限包括权限.用户请 ...
随机推荐
- 2D 3D 景深 动画 阴影
2D 二维的平面空间,让元素在X轴或者Y轴进行变化 2D里面的功能函数 2D-位移 2D-旋转 2D-缩放 2D-倾斜 变形属性 transform:: 位移:transform:translate( ...
- ABC330
D 记录每一行,每一列有多少个 o,然后统计答案即可. code E 想到 \(mex^{i \le n}_{i = 1} a_i \le n\) 这整个题就可做了(赛时因为没想到这个,痛失 \(47 ...
- chrome edge CORS 允许跨域
edge: edge://flags/#block-insecure-private-network-requests chrome: 在谷歌浏览器地址栏输入"chrome://flags/ ...
- Ton 区块链的官方 类ERC20-Token 智能合约代码-Transfer部分解析
作者:林冠宏 / 指尖下的幽灵.转载者,请: 务必标明出处. 掘金:https://juejin.im/user/1785262612681997 GitHub : https://github.co ...
- kettle从入门到精通 第六十九课 ETL之kettle kettle cdc mysql,轻松实现实时增量同步
1.之前kettle cdc mysql的时候使用的方案是canal+kafka+kettle,今天我们一起学习下使用kettle的插件Debezium直接cdc mysql. 注:CDC (Chan ...
- 安装Ingress-Nginx
目前,DHorse(https://gitee.com/i512team/dhorse)只支持Ingress-nginx的Ingress实现,下面介绍Ingress-nginx的安装过程. 下载安装文 ...
- Linux系统与网络管理
0. 背景 0.1 Unix Unix诞生于1969年 特点 多任务 多用户 多平台 保护模式 可移植操作系统接口(POSIX) 0.2 Linux 与Unix关系 类Unix系统,完全按照Unix的 ...
- Chrome插件:Vue.js Devtools 高效地开发和调试
在现代前端开发中,Vue.js因其灵活性和性能优势,受到越来越多开发者的青睐.然而,随着项目规模的扩大,调试和优化变得愈发复杂.幸运的是,Vue.js Devtools的出现,为开发者提供了一套强 ...
- MathType选项灰色无法点击或者word无法粘贴,治本解决方案
问题描述: mathtype安装过后,word中会出现mathtype的选项,但是这时mathtype中的选项是虚的,无法点击,而且此时word无法粘贴内容. 解决步骤: 1.打开word选项,点击加 ...
- 使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类就这么简单!
前言 今天大姚给大家分享一个.NET开源.免费.跨平台(支持Windows.Linux.macOS多个操作系统)的机器学习框架:ML.NET.并且本文将会带你快速使用ML.NET训练一个属于自己的图像 ...