当前位置: 首页 > news >正文

【SpringBoot】SpringBoot 中的 Shiro、Spring Security 学习过程及碰到的问题和解决方法

文章目录

  • 网站安全
  • Spring Security
    • 概念
    • 环境搭建
    • 用户认证和授权
      • 定义规则,编写基础配置类
      • 内容解析
        • Security的授权和认证的内容
        • thymeleaf 的 SpringSecurity 的整合
        • 登出注销流程
        • 内容显示
      • 测试项目
    • 设置跳转自己的登录页面和记住账号密码功能
      • 保存cookie账号
      • 跳转到自己的登录页
  • Shiro
    • 简介
      • 快速开始
      • shiro-springBoot-web
    • 新建一个shiro项目
    • Shiro导致项目出错
      • 查错,寻找解决方案
      • 手动注册Filter解决?,禁用自动配置,审慎使用AI
    • 继续排查
      • 前提
      • 对比项目差别点,检查自身错误
      • 检查错误信息
    • 测试Shiro
      • 编写认证授权的Relam
      • 控制器
      • 跳转的页面编写
      • 测试
    • 编写登录拦截
    • 实现用户认证
      • 根据`quickstart`,编写认证操作
      • 关联数据库实现用户认证
      • 设置加密
    • 实现用户授权
      • 准备工作
      • 关联数据库实现用户授权
    • 整合前端代码
      • 准备工作
      • 实现代码

网站安全

在Web开发过程中,安全是一个需要认真考虑的点。

一般在系统设计初期就要考虑进来,

如果应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,因而需要更多的开发时间,影响应用的发布进程。

一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。

  • 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。
  • 用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

Spring提供了一个功能强大的高度可定制的身份验证访问控制框架。它实际上是保护基于spring的应用程序的标准,也就是Spring Security

Spring Security

中文网站:https://springdoc.cn/spring-boot/web.html#web.security

概念

  1. Spring Security是一个框架,侧重于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring安全性的真正强大之处在于它可以轻松地扩展以满足定制需求
  2. Spring Security 框架对于Web安全都有很好的支持。
    1. 在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等
      1. 使用用户名、密码,有时与身份验证因素结合使用
    2. 在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。
      1. 在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
  3. 需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理
  4. 重要的几个类:
    1. WebSecurityConfigurerAdapter:自定义Security策略
    2. AuthenticationManagerBuilder:自定义认证策略
    3. AuthenticationManagerBuilder:自定义认证策略

环境搭建

  1. 创建项目
  2. 检查pom的配置,确保引入Spring Secutrity
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
  1. 导入静态资源

  1. 编写控制器跳转
package com.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class RouterController {@RequestMapping(value = {"/","/index"})public String index() {return "index";}@RequestMapping(value = "/toLogin")public String toLogin() {return "views/login";}@RequestMapping("/level1/{id}")public String toLevel1(@PathVariable Integer id) {return "views/level1/"+ id;}@RequestMapping("/level2/{id}")public String toLevel2(@PathVariable Integer id) {return "views/level2/"+ id;}@RequestMapping("/level3/{id}")public String toLevel3(@PathVariable Integer id) {return "views/level3/"+ id;}
}
  1. 尝试启动,拦截器拦截到login页面,环境搭建完成

用户认证和授权

定义规则,编写基础配置类

Spring Security 6.0 开始(对应 Spring Boot 3.0+),WebSecurityConfigurerAdapter 这个类已经被彻底移除,不再存在。

  1. 旧版的功能写法
package com.kuang.config;import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@EnableWebSecurity // 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {// 定制请求的授权规则// 首页所有人可以访问http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/level1/**").hasRole("vip1").antMatchers("/level2/**").hasRole("vip2").antMatchers("/level3/**").hasRole("vip3");// 开启自动配置的登录功能// /login 请求来到登录页// /login?error 重定向到这里表示登录失败http.formLogin();}//定义认证规则@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//在内存中定义,也可以在jdbc中去拿....//Spring security 5.0中新增了多种加密方式,也改变了密码的格式。//要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密//spring security 官方推荐的是使用bcrypt加密方式。auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3").and().withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3").and().withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2");}
} 
  1. 新版功能写法
@EnableWebSecurity
@Configuration
public class SecurityConfig  {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(request -> request.requestMatchers("/").permitAll()               // 允许所有人访问首页
//                .requestMatchers("/login").permitAll()               // 允许所有人访问首页.requestMatchers("/level1/**").hasRole("vip1")      // 允许vip1访问level1.requestMatchers("/level2/**").hasRole("vip2")      // 允许vip2访问level2.requestMatchers("/level3/**").hasRole("vip3")      // 允许vip3访问level3.anyRequest().authenticated()                 // 其他请求需要登录).formLogin(AbstractAuthenticationFilterConfigurer::permitAll).logout(LogoutConfigurer::permitAll);return http.build();}/*** 配置用户详情服务Bean* 该方法创建并配置一个基于内存的用户详情管理器,包含三个预定义用户:* 1. admin用户:拥有所有角色权限* 2. manager用户:拥有vip2和vip3角色权限* 3. employee用户:拥有vip3角色权限* 所有用户的初始密码都为"123456",使用委托密码编码器进行加密存储** @return UserDetailsService 用户详情服务实例*/@Beanpublic UserDetailsService userDetailsService() {// 创建委托密码编码器,支持多种密码编码方式PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();// 构建admin用户,拥有最高权限,包含所有角色UserDetails admin = User.builder().username("admin").password(encoder.encode("123456")).roles("vip1","vip2","vip3").build();// 构建manager用户,拥有中等级别权限UserDetails manager = User.builder().username("manager").password(encoder.encode("123456")).roles("vip2","vip3").build();// 构建普通employee用户,拥有基础权限UserDetails employee = User.builder().username("user").password(encoder.encode("123456")).roles("vip3").build();// 返回基于内存的用户详情管理器,包含所有预定义用户return new InMemoryUserDetailsManager(admin, manager, employee);}}

内容解析:

  1. 登录:.formLogin(AbstractAuthenticationFilterConfigurer::permitAll等同于.formLogin(form -> form .permitAll() ) 表示 登录页面和处理URL允许所有人访问,默认跳转到Spring SecurityLogin页面;
  2. 注销LogoutConfigurer::permitAll同上所述,说的是logout的方法;
  3. PasswordEncoder 作为密码编码器,将密码进行编码后存放到UserDetailspassword里面;
  4. InMemoryUserDetailsManager(admin, manager, employee)基于memory内存认证;

内容解析

Security的授权和认证的内容
  • Authentication(授权):Authentication :: Spring Security
  • Authentication(认证):
thymeleaf 的 SpringSecurity 的整合
  1. 导入整合依赖启动器
        <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency>
  1. 导入命名空间: xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
<!DOCTYPE html>
<html lang="en" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"xmlns:th="http://www.thymeleaf.org">  <!-- 主要是这行代码 官方建议使用 --><!--上述操作是加注释--><head><meta charset="UTF-8"><meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport"><title>首页</title><!--semantic-ui--><link href="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css" rel="stylesheet"><link rel="stylesheet" th:href="@{/qinjiang/css/qinstyle.css}"></head><body><!--主容器--><div class="ui container"><div class="ui segment" id="index-header-nav" th:fragment="nav-menu"><div class="ui secondary menu"><a class="item" th:href="@{/index}">首页</a><!--登录注销--><div class="right menu"><!--如果未登录--><div sec:authorize="!isAuthenticated()"><a class="item" th:href="@{/toLogin}"><i class="address card icon"></i> 登录</a></div><!--如果登录了 , 显示用户名与注销按钮--><div sec:authorize="isAuthenticated()"><a class="item">用户名: <span sec:authentication="name"></span>角色: <span sec:authentication="principal.authorities"></span></a></div><div sec:authorize="isAuthenticated()"><a class="item" th:href="@{/logout}"><i class="sign-out icon"></i> 注销</a></div><!--已登录<a th:href="@{/usr/toUserCenter}"><i class="address card icon"></i> admin</a>--></div></div></div><div class="ui segment" style="text-align: center"><h3>Spring Security Study by 秦疆</h3></div><div><br><div class="ui three column stackable grid"><!--菜单 , 根据用户的角色, 动态的实现-->
http://www.dtcms.com/a/332875.html

相关文章:

  • Spring Ai 如何配置以及如何搭建
  • SpringBoot系列之从繁琐配置到一键启动之旅
  • 银河麒麟服务器jar包部署自启动配置
  • L4 级别自动驾驶 硬件架构设计
  • JavaScript 基础实战:DOM 操作、数据类型与常见需求实现
  • LeetCode-17day:堆
  • 快速学会什么是gPRC
  • 【大模型微调系列-03】 大模型数学基础直观入门
  • 前端动画库之gsap
  • Android init.rc详解3
  • 机器学习之PCA
  • 八股文小记 Servlet 过滤器-Spring MVC 拦截器-Spring AOP 拦截器区别
  • Spring容器初始化源码解析
  • 深入解析MPLS网络中的路由器角色
  • 【java】对word文件设置只读权限
  • HTTP/2新型漏洞“MadeYouReset“曝光:可发动大规模DoS攻击
  • 代码随想录Day51:图论(岛屿数量 深搜广搜、岛屿的最大面积)
  • C#文件复制异常深度剖析:解决“未能找到文件“之谜
  • Ceph CSI 镜像删除流程与 Trash 机制失效问题分析文档
  • CISC 与 RISC 架构全面解析:从原理到应用
  • gulimall项目笔记:P54三级分类拖拽功能实现
  • 《Attention-driven GUI Grounding》论文精读笔记
  • CSS Houdini 与 React 19 调度器:打造极致流畅的网页体验
  • 【Redis】Redis典型应用——分布式锁
  • 【Redis】分布式系统的演化过程
  • KNN 算法
  • 高频量化详解,速度和程序化的满足!
  • 卷积神经网络(CNN)学习笔记
  • 基本电子元件:贴片电阻器的种类
  • 序列晋升6:ElasticSearch深度解析,万字拆解