【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管理权限包括权限.用户请 ...
随机推荐
- react移动端组件antd-mobile
使用react移动端组件antd-mobile完成底部导航功能实现. 官网:https://mobile.ant.design/docs/react/introduce-cn antd-mobile ...
- [SHOI2011]双倍回文 题解
[SHOI2011]双倍回文 题解 看了一些写回文自动机的大佬的代码,我深感敬畏,于是我转身向Manacher走去 现在荣登最优解第一页-- 说实话,这个方法的复杂度是很玄学的,但是加了一些优化之后, ...
- Easysearch压缩模式深度比较:ZSTD+source_reuse的优势分析
引言 在使用 Easysearch 时,如何在存储和查询性能之间找到平衡是一个常见的挑战.Easysearch 具备多种压缩模式,各有千秋.本文将重点探讨一种特别的压缩模式:zstd + source ...
- work08
day09作业: 必做题:========================================第一题: 1.定义一个Animal类,包含如下行为: eat() 打印"要吃饭&qu ...
- 使用spark-sql处理Doris大表关联
背景 最近项目上有一个需求,需要将两张表(A表和B表)的数据进行关联并回写入其中一张表(A表),两张表都是分区表,但是关联条件不包括分区字段. 分析过程 方案一 最朴素的想法,直接关联执行,全表关联, ...
- Tarjan 求有向图的强连通分量
重温Tarjan, 网上看了许多博客感觉都讲的不清楚. 故传上来自己的笔记, 希望帮到大家. 提到的一些概念可以参考 oi wiki, 代码也是 oi wiki 的, 因为我不认为我能写出比大佬更好的 ...
- js中对对象经行判空
1.for (... in ...) for(var i in obj){ return true; //如果不为空,返回true } return false; //如果为空,返回false 2.J ...
- FreeRDP使用,快速找出账户密码不正确的服务器地址
最近有个需求,需要找出服务器未统一设置账户密码的服务器,进行统一设置,一共有一百多台服务器,一个个远程登录看,那得都费劲啊,这时候就可以用到FreeRDP这个远程桌面协议工具,FreeRDP下载,根据 ...
- 运行前端React框架出现node Error: bind EADDRINUSE null的解决方法
运行前端React代码时,出现这样的错误: node Error: bind EADDRINUSE null 后来发现端口号冲突,换个端口号后问题就可以解决了.
- 基于 Three.js 的 3D 模型加载优化
作者:来自 vivo 互联网前端团队- Su Ning 作为一个3D的项目,从用户打开页面到最终模型的渲染需要经过多个流程,加载的时间也会比普通的H5项目要更长一些,从而造成大量的用户流失.为了提升首 ...