【SpringSecurity】快速入门—通俗易懂

目录

1.导入依赖

2.继承WebSecurityConfigurerAdapter

3.实现UserDetailsService

4.记住我

5.用户注销

6.CSRF理解

7.注解功能

7.1@Secured

7.2@PreAuthorized 

7.3@PostAuthorized

7.4@PostFilter

7.5Z@PreFilter

8.原理解析

1.导入依赖

首先,在pom.xml文件中添加Spring Security依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
</dependencies>

2.继承WebSecurityConfigurerAdapter

创建一个WebSecurityConfig类,继承WebSecurityConfigurerAdapter:

继承WebSecurityConfigurerAdapter是因为我们要重写里面的方法 定义一些安全配置 例如:注销

功能、访问控制、登录页面等。

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {}

protected void configure(HttpSecurity http)这个方法用于配置拦截保护的HTTP请求 配置HTTP安

全性 定义哪些URL应该受到保护 哪些用户可以访问哪些URL 以及保护的URL应该执行哪些安全措

	@Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin()//.loginPage("/login.html")//指定登录页面(这里不会前端,所以不写页面了)//.loginProcessingUrl("/authentication/form")//登录访问路径(登录页面的form表单提交路径)//.failureUrl("/error.html")//用户名或密码错误访问的页面//.usernameParameter("username")//.passwordParameter("password")   //要认证的 用户名, 密码  的参数名,默认username, password.defaultSuccessUrl("/index/toIndex").permitAll()//defaultSuccessUrl:登录成功后,是否始终跳转到登录成功url,它默认为false。  permitAll()就是指不需要拦截.and().authorizeRequests().antMatchers("/index/testRoleAndPermission").hasAnyRole("admin")//设置哪些路径需要什么权限.antMatchers("/index/anyOne","/index/anyTwo").permitAll()//设置哪些路径可以直接访问,不需要认证.anyRequest().authenticated();//其余任何请求都需要认证.and().csrf().disable();//关闭csrf防护}

public void configure(AuthenticationManagerBuilder auth) 这个方法主要是配置 身份验证机制 就

是配置密码匹配器和用户从数据库查询用户的service

// 用于配置身份验证机制// AuthenticationManagerBuilder常用方法:(下面的方法我没有写参数,实际情况可能是有参的)// inMemoryAuthentication(): 这个方法允许您在内存中配置用户详细信息。您可以指定用户名、密码和用户角色。这对于快速测试和开发目的非常方便。// userDetailsService(): 这个方法接受一个UserDetailsService对象,用于加载用户的详细信息。UserDetailsService是一个接口,您需要实现它来根据用户名加载用户信息。// jdbcAuthentication(): 这个方法允许您使用JDBC来加载用户详细信息。您需要提供一个DataSource对象和相应的查询语句来检索用户名、密码和角色信息。// ldapAuthentication(): 这个方法用于配置LDAP(轻量级目录访问协议)身份验证。您需要提供LDAP服务器的连接信息和相应的查询语句。// authenticationProvider(): 这个方法允许您提供自定义的AuthenticationProvider实现,用于验证用户的身份。// userDetailsService(T userDetailsService):    根据传入的自定义UserDetailsService做身份验证。// 返回值:                                       会返回一个DaoAuthenticationConfigurer(该类继承AbstractDaoAuthenticationConfigurer抽象类)}// passwordEncoder(PasswordEncoder passwordEncoder): 来自于抽象类, 用于指定自定义密码匹配器,便于后续springsecutiry底层后续使用。@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}

public PasswordEncoder passwordEncoder() 这个是密码匹配器 SpringSecurity校验密码的时候

就要用到密码匹配器 对密码进行加密解密校验对比操作

// 必须要个这种密码匹配器,springsecurity要求的,必须对密码进行加密。@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}

3.实现UserDetailsService

客户端输入用户名和密码 后端必须要从数据库查询出数据 进行校验 需要实现UserDetailsService

重写查询校验方法

/*** @author lihao* @version 1.0* @ClassName SecurityUserServiceImpl* @date 2023/5/25  9:43* @apiNote UserDetailsService:用于加载用户的详细信息,以供身份验证和授权使用。它提供了一个方法loadUserByUsername(String username)用于用户名获取用户的详细信息。*                              我们想更改springcurity的认证,我们就可以实现UserDetailsService,因为security底层就是用其做核心认证的。**/
@Service
public class SecurityUserServiceImpl extends ServiceImpl<SecurityUserMapper, SecurityUser> implements SecurityUserService, UserDetailsService {@Resourceprivate SecurityUserMapper securityUserMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {LambdaQueryWrapper<SecurityUser> wrapper = new LambdaQueryWrapper<>();wrapper.eq(SecurityUser::getUsername,username);SecurityUser user = securityUserMapper.selectOne(wrapper);if (user==null) {throw new UsernameNotFoundException("用户没找到");}// loadUserByUsername方法需要返回一个UserDetails(接口),常用实现类User。因此我们返回一个SpringSecurity提供的User对象。// 该User对象所需的参数中,密码必须加密(由springsecurity要求),因为我前面已经在SecurityConfig配置了加密器,所以这里就不需要对密码进行加密。// 否则需要加密:new BCryptPasswordEncoder().encode(user.getPassword())  ---- 可以这么写// 第三个参数,他需要一个权限集合,这里只做认证,所以随便搞一个角色集合,不影响认证,注意,这里第三个参数不能直接传null,必须给它一个集合。List<GrantedAuthority> adminAuthority = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");return new User(user.getUsername(), user.getPassword(), adminAuthority); // 已在SecurityConfig配置了加密组件,所以不需要对这里的密码加密。}

4.记住我

客户端登录一次以后 下次访问不用登录 直接访问 

需要在configure(HttpSecurity http)配置

// 开启记住我功能
http.rememberMe().tokenRepository(tokenRepository).userDetailsService(usersService);

 .tokenRepository(tokenRepository):这是为"记住我"功能配置token存储库。token是用来存储

和验证用户会话信息的。这通常是一个在数据库或其他持久性存储中保存信息的对象。

.userDetailsService(usersService):这是为"记住我"功能配置用户详情服务。

UserDetailsService是Spring Security中的一个接口,它有一个方法loadUserByUsername,用于根

据用户名获取用户信息。usersService需要实现这个接口,并能够根据用户名找到用户的详细信

息。这对于"记住我"功能很重要,因为它需要知道用户的详细信息(例如他们的加密密码)以验证

他们的身份。

@Autowired
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository(){JdbcTokenRepositoryImpl jdbcTokenRepository = new 
JdbcTokenRepositoryImpl();
// 赋值数据源
jdbcTokenRepository.setDataSource(dataSource);
// 自动创建表,第一次执行会创建,以后要执行就要删除掉!
jdbcTokenRepository.setCreateTableOnStartup(true);
return jdbcTokenRepository;}
}

还可以设置有效期

5.用户注销

http.logout().logoutUrl("/logout").logoutSuccessUrl("/index").permitAll
();
  1. http.logout(): 这是调用Spring Security的HTTP安全性配置的logout方法,它配置了用户的注销功能。
  2. .logoutUrl("/logout"): 这告诉Spring Security,当用户点击注销时,应该将他们重定向到URL "/logout"。这通常是应用程序的一个特殊页面,它执行注销操作并终止用户的会话。
  3. .logoutSuccessUrl("/index"): 当注销操作成功后,用户将被重定向到这个URL。在这个例子中,用户将被重定向到应用程序的"/index"页面。
  4. .permitAll(): 这告诉Spring Security,所有用户都应该能够访问注销功能。换句话说,它不限制谁可以注销,所有用户都可以。

总的来说,这段代码的目的是配置Spring Security的注销功能,使得所有用户都可以注销,并且当

他们注销成功后,他们将被重定向到应用程序的"/index"页面。

6.CSRF理解

跨站请求伪造 (英语: Cross-site request forgery ),也被称为 one-click
attack 或者 session riding ,通常缩写为 CSRF 或者 XSRF , 是一种挟制用户在当前已
登录的 Web 应用程序上执行非本意的操作的攻击方法。跟 跨网站脚本 XSS )相比, XSS
利用的是用户对指定网站的信任, CSRF 利用的是网站对用户网页浏览器的信任。
跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个
自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买
商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。
这利用了 web 中用户身份验证的一个漏洞: 简单的身份验证只能保证请求发自某个用户的
浏览器,却不能保证请求本身是用户自愿发出的
Spring Security 4.0 开始,默认情况下会启用 CSRF 保护,以防止 CSRF 攻击应用
程序, Spring Security CSRF 会针对 PATCH POST PUT DELETE 方法进行防护。
开启CSRF后,Spring Security会添加一个CSRF令牌到表单提交的请求中,以确保只有合法的请
求才能被处理。这样可以防止攻击者通过注入恶意代码或跨站请求伪造等方式来篡改服务器资源。

7.注解功能

使用注解功能前 要先开启注解功能 在启动类加上@EnableGlobalMethodSecurity()注解 注解里面

要使用什么注解 就在括号里填写 xxx注解=true 例如:

@EnableGlobalMethodService(securedEnabled = true) 使用@securedEnabled注解

@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled=true)
public class DemosecurityApplication {
public static void main(String[] args) {SpringApplication.run(DemosecurityApplication.class, args);}
}

7.1@Secured

判断是否具有这个角色 字符串前缀需要添加ROLE_

// 测试注解:
@RequestMapping("testSecured")
@ResponseBody
@Secured({"ROLE_normal","ROLE_admin"})
public String helloUser() {
return "hello,user";
}

7.2@PreAuthorized 

先开启注解功能:
@EnableGlobalMethodSecurity (prePostEnabled = true )
@PreAuthorize:注解适合进入方法前的权限验证, @PreAuthorize 可以将登录用
户的 roles/permissions 参数传到方法中。
@RequestMapping("/preAuthorize")
@ResponseBody
//@PreAuthorize("hasRole('ROLE_管理员')")
@PreAuthorize("hasAnyAuthority('menu:system')")
public String preAuthorize(){System.out.println("preAuthorize");
return "preAuthorize";
}

7.3@PostAuthorized

先开启注解功能:
@EnableGlobalMethodSecurity (prePostEnabled = true )
@PostAuthorize 注解使用并不多,在方法执行后再进行权限验证,适合验证带有返回值
的权限 .
@RequestMapping("/testPostAuthorize")
@ResponseBody
@PostAuthorize("hasAnyAuthority('menu:system')")
public String preAuthorize(){System.out.println("test--PostAuthorize");
return "PostAuthorize";
}

7.4@PostFilter

@PostFilter :权限验证之后对数据进行过滤 留下用户名是 admin1 的数据
表达式中的 filterObject 引用的是方法返回值 List 中的某一个元素
@RequestMapping("getAll")
@PreAuthorize("hasRole('ROLE_管理员')")
@PostFilter("filterObject.username == 'admin1'")
@ResponseBody
public List<UserInfo> getAllUser(){ArrayList<UserInfo> list = new ArrayList<>();list.add(new UserInfo(1l,"admin1","6666"));list.add(new UserInfo(2l,"admin2","888"));
return list;
}

7.5Z@PreFilter

@PreFilter: 进入控制器之前对数据进行过滤
@RequestMapping("getTestPreFilter")
@PreAuthorize("hasRole('ROLE_管理员')")
@PreFilter(value = "filterObject.id%2==0")
@ResponseBody
public List<UserInfo> getTestPreFilter(@RequestBody List<UserInfo> 
list){list.forEach(t-> {System.out.println(t.getId()+"\t"+t.getUsername());});
return list;
}

8.原理解析

SpringSecurity本质:其实就是一个过滤器链,内部提供了各种功能的过滤器。springsecurity底层就是这些过滤器一层一层的执行帮我们实现的权限管理。

图中只展示了核心过滤器,其它的非核心过滤器并没有在图中展示。

UsernamePasswordAuthenticationFilter: 用于处理基于表单的登录请求,从表单中获取用户名和

密码。 默认情况下处理来自 /login 的请求。从表单中获取用户名和密码时,默认使用的表单 name

值为 username 和 password。 这两个值可以通过设置这个过滤器的usernameParameter 和

passwordParameter 两个参数的值进行修改。 其内部还有 登录成功 或 失败后 进行处理的

AuthenticationSuccessHandler 和 AuthenticationFailureHandler,这些都可以根据需求做相关改

变。

ExceptionTranslationFilter: 处理 AccessDeniedException 和 AuthenticationException 异常。 3.

FilterSecurityInterceptor: 是用于保护web资源的,使用 AccessDecisionManager 对当前用户进

行授权访问。

SpringSecurity认证流程:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/177316.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matplotlib入门-基金走势图

一、matplotlib简介 matplotlib是一个Python 2D绘图库&#xff0c;开发者仅需要几行代码就可以生成曲线图、柱状图、散点图甚至动画。需要另外安装&#xff0c;一条命令搞定。 pip install matplotlib 它的绘图接口在matplotlib.pyplot模块中&#xff0c;pyplot提供和MATLIB…

Mac终端学习

命令1&#xff1a;ifconfig 作用&#xff1a;列出本机所有的网络设备以及其上面的配置&#xff0c;主要指的是ip地址和mac地址 其他用法&#xff1a;sudo ifconfig en4 add 10.10.10.12 netmask 255.255.255.0 作用&#xff1a;给en4加入别的网段 其他用法&#xff1a;sudo i…

让你笑到不行的笑话短视频接口,快来试试!

11在当今这个快节奏的社会中&#xff0c;笑话成为了许多人调节情绪的有效方法。如今&#xff0c;短视频平台已经成为了最受欢迎的娱乐方式之一&#xff0c;因此&#xff0c;将笑话和短视频结合起来&#xff0c;成为了一种很有趣的方式来带给我们欢乐。今天我们要介绍的是挖数据…

JMeter的使用——傻瓜式学习【下】

目录 前言 1、自动录制脚本 1.1、原理 1.2、JMeter脚本录制 2、JMeter直连数据库 2.1、直连数据库的作用 2.2、JMeter直连数据库的步骤 案例&#xff1a; 3、JMeter的逻辑控制器 3.1、if控制器 案例&#xff1a; 3.2、循环控制器 案例&#xff1a; 3.3、ForEach控…

NB-IOT的粮库挡粮门异动监测装置

一种基于NBIOT的粮库挡粮门异动监测装置,包括若干个NBIOT开门监测装置,物联网后台管理系统,NBIOT低功耗广域网络和用户访问终端;各个NBIOT开门监测装置通过NBIOT低功耗广域网络与物联网后台管理系统连接,物联网后台管理系统与用户访问终端连接.NBIOT开门监测装置能够对粮库挡粮…

从瀑布模式到水母模式:ChatGPT如何赋能软件研发全流程

文章目录 前言内容简介作者简介专家推荐读者对象直播预告 前言 计算机技术的发展和互联网的普及&#xff0c;使信息处理和传输变得更加高效&#xff0c;极大地改变了金融、商业、教育、娱乐等领域的运作方式。数据分析、人工智能和云计算等新兴技术&#xff0c;也在不断地影响和…

Gcov 查看代码覆盖率

GCOV 工具简介 gcov是一个测试代码覆盖率的工具。 它是 gcc 自带的查看代码覆盖率的工具&#xff0c;无需额外安装&#xff0c;在嵌入式的 arm-eabi-none-gcc 中同样可以使用&#xff08;需要重写部分系统函数&#xff09;。 使用效果如下图所示&#xff1a; 程序运行完成后…

Ubuntu自建git服务器

Ubuntu 安装 gitlab-ce sudo apt-get update sudo apt-get install gitlab-ce 安装成功 sudo apt-get install gitlab-ce 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 下列【新】软件包将被安装&#xff1a;gitlab-ce 升…

GitHub项目监控

目录 github开放平台接口限流 监控某个仓库的更新状态 对于常用Github的用户来说&#xff0c;经常有一些自动化的需求。比如监控某些项目的更新情况并实时拉取&#xff0c;比如监控github全网上传的代码是否携带了公司的APIKEY&#xff0c;SECRETKEY等… github开放平台 gith…

26 行为型模式-命令模式

1 命令模式介绍 2 命令模式原理 3 命令模式实现 模拟酒店后厨的出餐流程,来对命令模式进行一个演示,命令模式角色的角色与案例中角色的对应关系如下: 服务员: 即调用者角色,由她来发起命令. 厨师: 接收者,真正执行命令的对象. 订单: 命令中包含订单 /*** 订单类**/ public cl…

2023年Zotero最新同步教程-使用TeraCloud的25G免费空间实时跨设备同步文献

文章目录 1. 前言2.1. 注册账号2.1.1. 填写注册信息2.1.2. 创建账号成功2.1.3. 注意2.2. 扩容空间2.3. 打开WebDAV 3. Zotero配置WebDAV同步3.1. 设置网址3.2. 验证服务器3.3. 文件同步成功 4. 结语 1. 前言 Zotero免费版的存储空间是300m&#xff0c;一个图文PDF动辄两三M&am…

智慧灌溉平台

1.知识百科 智慧灌溉是运用物联网、云计算、大数据等新一代信息技术&#xff0c;结合农业生产的实际需求&#xff0c;通过传感器采集土壤温湿度、光照强度等信息&#xff0c;利用无线传感网络传输到中央控制系统进行智能控制。智慧灌溉系统由传感器&#xff08;水位传感器&…

YOLOv5优化:独家创新(SC_C_Detect)检测头结构创新,实现涨点 | 检测头新颖创新系列

💡💡💡本文独家改进:独家创新(SC_C_Detect)检测头结构创新,适合科研创新度十足,强烈推荐 SC_C_Detect | 亲测在多个数据集能够实现大幅涨点 目录 1. SC_C_Detect介绍 2. SC_C_Detect加入YOLOv5 2.1 新建models/head_improve.py

基础课15——语音标注

语音数据标注是对语音数据进行处理和分析的过程&#xff0c;目的是让人工智能系统能够理解和识别语音中的信息。这个过程包括了对语音信号的预处理、特征提取、标注等步骤。 在语音数据标注中&#xff0c;标注员需要对语音数据进行分类、切分、转写等操作&#xff0c;让人工智…

京东平台数据分析:2023年9月京东扫地机器人行业品牌销售排行榜

鲸参谋监测的京东平台9月份扫地机器人市场销售数据已出炉&#xff01; 根据鲸参谋平台的数据显示&#xff0c;9月份&#xff0c;京东平台扫地机器人的销量近14万&#xff0c;环比增长约2%&#xff0c;同比降低约4%&#xff1b;销售额为2.9亿&#xff0c;环比降低约4%&#xff0…

GORM:在Go中轻松管理数据库

GORM综合介绍 - Go对象关系映射库 在现代软件开发中&#xff0c;高效的数据库管理对于构建强大的应用程序至关重要。GORM是Go开发人员寻求与数据库进行交互的简化方式的宝贵工具。GORM是Go对象关系映射的缩写&#xff0c;它为Go的面向对象世界与数据库的关系世界之间提供了桥梁…

获取Webshell方法

CMS系统指的是内容管理系统。已经有别人开发好了整个网站的前后端&#xff0c;使用者只需要部署cms&#xff0c;然后通过后台添加数据&#xff0c;修改图片等工作&#xff0c;就能搭建好一个的WEB系统。 CMS获取Webshell方法 WordPress后台拿Webshell phpcms拿Webshell 非CMS…

FedAT:异步更新联邦学习方法

文章链接&#xff1a;FedAT: A Communication-Efficient Federated Learning Method with Asynchronous Tiers under Non-IID Data 发表会议: SC’21 (International Conference for High Performance Computing, Networking, Storage, and Analysis) 高性能计算&#xff0c;体…

【Cocos新手进阶】使用cocos 的预制体创建动态的滚动框组件。

本篇文章主要讲解&#xff0c;使用cocos 游戏引擎制作动态生成的滚动框实例教程。 日期&#xff1a;2023年11月1日 作者&#xff1a;任聪聪 引擎版本&#xff1a;2.4.3 至 2.4.11 关于预制体的说明和概念 cocos中的预制体的作用是能够让你使用数据的形式进行控制界面的变化&am…

Python web开发中的单元测试自动化技巧!

Python作为一种广泛使用的编程语言&#xff0c;在web开发中也扮演着重要的角色。在进行web开发时&#xff0c;单元测试是一个不可或缺的环节。单元测试可以确保代码的正确性&#xff0c;并且能够在开发过程中快速发现问题&#xff0c;有助于提高代码质量和开发效率。 在Python…