【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.mzph.cn/news/124910.shtml

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

相关文章

计算机网络-IP地址

文章目录 子网划分定长子网划分子网划分的方法子网掩码 可变长子网划分 无类别编址网络前缀路由聚合 特殊用途的IP地址专用网络地址链路本地地址运营商级NAT共享地址用于文档的测试网络地址 IP地址的规划和分配IP地址的规划和分配方法IP地址的规划和分配实例 子网划分 定长子网…

文章分类管理接口

目录 前言 新建表 获取文章分类列表接口 初始化路由模块 将路由对象导出并使用 初始化路由对象处理函数 修改路由代码 导入数据库 定义sql语句 调用db.query() 完整的获取文章分类列表处理函数 新增文章分类接口 定义路由和处理函数 验证表单数据 查询分类名称与…

UDP网络编程的接受与发送信息

/发送端B>可以接受数据 public class UDPSenderB {public static void main(String[] args) throws IOException {//创建一个DatagramSocket 对象&#xff0c;准备发送和接受数据DatagramSocket socket new DatagramSocket(9998);//将需要发送的数据&#xff0c;封装到Data…

空号检测API如何助力于提高客户关系管理

引言 在现代商业世界中&#xff0c;客户关系管理已经成为企业成功的关键要素之一。CRM不仅涉及到如何吸引新客户&#xff0c;还包括如何维护并与现有客户建立持久而有益的关系。在这个过程中&#xff0c;通信是至关重要的。为了确保您的客户数据库保持最新和准确&#xff0c;空…

navicat15 恢复试用方法

1.运行&#xff0c;输入regedit&#xff0c;打开注册表 2.注册表中搜索 HKEY_CURRENT_USER\Software\PremiumSoft\NavicatPremium&#xff0c;删除下面的Registration15XCS文件夹 3.注册表中再搜索 HKEY_CURRENT_USER\Software\Classes\CLSID 然后拉到文件夹目录的最后&#x…

「永不失联」产品创新与升级系列发布,预约直播“即将发车”

数字化浪潮下&#xff0c;北斗时空智能正成为我国重要的新型基础设施。 通过将卫星定位精度提升至厘米级乃至毫米级&#xff0c;时空智能满足了数字化时代智能驾驶、共享出行、智慧城市等多种智能终端对时空信息的爆发式增长需求&#xff0c;同步印证着测绘地理信息领域的技术应…

什么是Vue.js中的指令(directive)?举例说明一些常见的指令。

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

Azure机器学习 - 使用与Azure集成的Visual Studio Code实战教程

本文介绍如何启动远程连接到 Azure 机器学习计算实例的 Visual Studio Code。 借助 Azure 机器学习资源的强大功能&#xff0c;使用 VS Code 作为集成开发环境 (IDE)。 在VS Code中将计算实例设置为远程 Jupyter Notebook 服务器。 关注TechLead&#xff0c;分享AI全维度知识。…

Spring本地jar包依赖项目改为maven依赖

1.简介 我们在做项目的时候&#xff0c;可能会偶尔接手较为古老的项目&#xff0c;这些项目使用了较为老旧的版本管理或依赖管理方法&#xff0c;对于新开发项目来说&#xff0c;这些老旧的依赖管理方式会影响开发效率&#xff0c;所以&#xff0c;一般我们会选择将老项目的依…

JavaEE入门介绍,HTTP协议介绍,常用状态码及含义,服务器介绍(软件服务器、云服务器)

一、JavaEE入门 JavaEE&#xff08;Java Enterprise Edition&#xff09;&#xff0c;Java企业版&#xff0c;是一个用于企业级web开发&#xff08;不需要使用控制台&#xff09;平台。最早由Sun公司定制并发布&#xff0c;后由Oracle负责维护。 JavaEE平台规范了在开发企业级w…

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

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

HarmonyOS开发:基于http开源一个网络请求库

前言 网络封装的目的&#xff0c;在于简洁&#xff0c;使用起来更加的方便&#xff0c;也易于我们进行相关动作的设置&#xff0c;如果&#xff0c;我们不封装&#xff0c;那么每次请求&#xff0c;就会重复大量的代码逻辑&#xff0c;如下代码&#xff0c;是官方给出的案例&am…

Ubuntu安装ddns-go使用阿里ddns解析ipv6

Ubuntu安装ddns-go 1.何为ddns-go2.安装环境3.获取ddns-go安装包4.解压ddns-go5.安装ddns-go6.配置ddns-go 1.何为ddns-go DDNS-GO是简单好用的DDNS&#xff0c;它可以帮助你自动更新域名解析到公网IP。比如你希望在本地部署网站&#xff0c;但是因为公网IP是动态的&#xff0…

【Linux】虚拟机项目部署与发布

目录 一、Linux部署单机项目 1.1 优缺点 1.2 将项目共享到虚拟机 1.3 解压后将war包放入tomcat 1.4 数据库导入脚本 1.5 Tomcat启动项目 二、部署前后端分离项目 2.1 准备工作 2.2 部署SPA项目 2.2.1 nginx反向代理 2.2.2 SPA项目宿主机访问 一、Linux部署单机项目…

854数据结构简答题---图

1.&#xff08;2015期末&#xff09;已知无环路有向图如图3.1,请在表2、表3中填写出各事件的最早发生时间、最迟发生时间、活动的最早、最迟开始时间&#xff0c;给出关键活动及关键路径。 从源点到汇点的有向路径可能有多条&#xff0c;所有路径中&#xff0c;具有最大路径长…

CodeWhisperer 初体验

文章作者&#xff1a;1颗 orange 最近用了一个叫 CodeWhisperer 的插件&#xff0c;这个软件对于来说开发人员&#xff0c;插件有好多实用的功能&#xff0c;编码更高效&#xff0c;代码质量也提升了很多。 CodeWhisperer 简介 CodeWhisperer 是亚⻢逊出品的一款基于机器学习…

SRA ToolKit (sra-tools) 的安装和使用

文章目录 前言从哪里下载 SRA ToolKit如何安装怎么用 前言 事情的起因是从NCBI SRA Database下载数据时的一个报错&#xff1a;   path not found while resolving tree within virtual file system module - SRR17****** cannot be found 上次下载数据的时候还是上次&…

Kafka设计原理详解

Kafka核心总控制器Controller 在Kafka集群中会有一个或者多个broker&#xff0c;其中有一个broker会被选举为控制器&#xff08;Kafka Controller&#xff09;&#xff0c;它负责管理整个集群中所有分区和副本的状态。 当某个分区的leader副本出现故障时&#xff0c;由控制器…

Leetcode刷题详解——下降路径最小和

1. 题目链接&#xff1a;931. 下降路径最小和 2. 题目描述&#xff1a; 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一行选择…

SpringBoot集成与应用Neo4j

文章目录 前言集成使用定义实体配置定义Repository查询方法方式一&#xff1a;Query方式二&#xff1a;Cypher语法构建器方式三&#xff1a;Example条件构建器方式四&#xff1a;DSL语法 自定义方法自定义接口继承自定义接口实现自定义接口neo4jTemplateNeo4jClient 自定义抽象…