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

spring |Spring Security安全框架 —— 认证流程实现

文章目录

    • 开头
    • 简介
    • 环境搭建
    • 入门使用
      • 1、认证
        • 1、实体类
        • 2、Controller层
        • 3、Service层
          • 3.1、接口
          • 3.2、实现类
          • 3.3、实现类:UserDetailsServiceImpl
        • 4、Mapper层
        • 3、自定义token认证filter
    • 注意事项
    • 小结

开头

  • Spring Security 官方网址:Spring Security官网

开头贴官网,有事找官方!

在这里插入图片描述

简介

介绍的话不多说,就一句:

  • Spring Security 是一个安全管理框架。

    • 一般用于中大型项目。小项目使用shiro,shiro上手简单。
    • 不过,一般是这样。小项目练手用也是相当可以的。

好吧!这是三句话,没跑。

环境搭建

基于SpringBoot3搭建的项目,妥妥好用。

组件SpringBoot2.XSpringBoot3.X
JDKJDK 8、9JDK 17+
JPAJPA2.0+JPA3.0+
ServletServlet 3.1+Servlet 5.0
SpringSpring Framework 5+Spring Framework 6+
GradleGradle 4.xGradle7.3

1、依赖导入

	<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.4</version></parent><!--        spring web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!--        spring Security--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!--        mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.7</version></dependency><!--    mysql驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency>

2、配置文件

spring:datasource:url: jdbc:mysql://localhost:3306/dataBase?characterEncoding=utf-8&serverTimezone=Asia/Shanghaiusername: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver
# mybatisPlus 配置
mybatis-plus:configuration:map-underscore-to-camel-case: true# 日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:#      逻辑删除logic-delete-field: delFaglogic-delete-value: 1logic-not-delete-value: 0#      主键自增id-type: auto

入门使用

1、认证

废话不多说,贴个认证流程图:

在这里插入图片描述

1、SpringSecurity Config类


//整点实在的,一整套流程,绝对全面。
@Configuration
@EnableWebSecurity
public class SecurityConfig {@Autowiredprivate AuthenticationTokenFilter tokenFilter;@Autowiredprivate AuthenticationEntryPointImpl authenticationEntryPoint;/*PasswordEncoder是一个用于密码加密的接口,它封装了多种主流的加密方法,它们用于密码的安全存储和校验。但计算开销也相对较大,因此在面对高并发性能要求的大型信息系统时:推荐使用会话、OAuth、Token等短期加密策略来实现系统的信息安全。*/@Beanpublic PasswordEncoder getPasswordEncoder(){return new BCryptPasswordEncoder();}/*负责注册为应用程序提供认证服务的 。*/@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration config ) throws Exception {return config.getAuthenticationManager();}/*Security Filter是通过FilterChainProxy而不是DelegatingFilterProxy注册进SecurityFilterChain的。	过滤器链,配置*/@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception{http.csrf(csrf -> csrf.disable()); //关闭csrf防护http.authorizeHttpRequests(auth ->auth.requestMatchers("/user/login")//请求路径匹配.permitAll()//放行,不作拦截.anyRequest()//其他请求.authenticated());//认证//        自定义token 认证,用于登录后续请求放行。通过springSecurity上下文判断http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);return http.build();}
1、实体类
//主要就是用:username和 password
@Data
public class SysUser implements Serializable {private static final long serialVersionUID = 662137028719131857L;private Long id;
/*** 用户名*/private String username;
/*** 昵称*/private String nickname;
/*** 密码*/private String password;
/*** 用户类型:0:普通 1:管理员*/private String type;
/*** 账号状态:0:正常 1:停用*/private String status;
/*** 邮箱*/private String email;
/*** 手机号*/private String phoneNumber;
/*** 用户性别(0:男 1:女 2 :匿名)*/private String sex;
/*** 头像*/private String avatar;private Integer isDelete;}
2、Controller层
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate SysUserService userService;@PostMapping("/login")public R login(@RequestBody SysUser user){return userService.login(user);}
}
3、Service层
3.1、接口
public interface SysUserService extends IService<SysUser> {/*** 登录* @param user* @return*/R login(SysUser user);
}
3.2、实现类
@Service
public class SysUserServiceImpl extends ServiceImpl<UserMapper, SysUser> implements SysUserService {@Autowiredprivate AuthenticationManager authenticationManager;@Overridepublic R login(SysUser user) {//重写userDetailsService 处理UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());Authentication authenticate = authenticationManager.authenticate(authenticationToken);if(Objects.isNull(authenticate)){throw new AppException(AppExceptionMsgEnum.LOGIN_ERROR);}//jwt令牌信息//……LoginUser loginuser = (LoginUser) authenticate.getPrincipal();//自定义返回return  R.success(loginuser.getUser());}
}
3.3、实现类:UserDetailsServiceImpl
  • 用于用户信息认证处理
@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(SysUser::getUsername,username);SysUser userResult = userMapper.selectOne(queryWrapper);if(Objects.isNull(userResult)){throw new AppException(AppExceptionMsgEnum.LOGIN_ERROR);}return new LoginUser(userResult);}
}
4、Mapper层
public interface UserMapper extends BaseMapper<SysUser> {
}
3、自定义token认证filter

@Component
public class AuthenticationTokenFilter extends OncePerRequestFilter {@Autowiredprivate UserMapper userMapper;@Overrideprotected void doFilterInternal(HttpServletRequest request,  HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, ServletException, IOException {//获取tokenString token = request.getHeader("token");String uri = request.getRequestURI();if(uri.equals("/gate/logout")){filterChain.doFilter(request,response);return;}//放行未携带token 的请求,交由后面拦截器处理if (token == null) {filterChain.doFilter(request,response);return;}//获取用户信息,这里由于没有使用jwt,所以仿制了一下SysUser user = new SysUser();user.setUsername(token);LoginUser loginUser = new LoginUser();loginUser.setUser(user);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null,null);//存储到SecurityContextHolderSecurityContextHolder.getContext().setAuthentication(authenticationToken);//放行filterChain.doFilter(request,response);}}

注意事项

  1. 认证失败后,会抛出异常。使用全局异常处理器 + 自定义异常 使用。
  • 自定义返回类
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)// 属性为NULL 不序列化
public class R<T> {private int status;//    private boolean success;private String message;private T data;@JSONField(format="yyyy-MM-dd HH:mm:ss")private DateTime time;/*** 正确result* @param data* @param <T>* @return*/public static <T> R<T> success(T data){R<T> r = new R<>();
//        r.success = true;r.status = 200;r.data = data;r.message = "successful";r.time = DateTime.now();return r;}public static <T> R<T> success(String msg ,T data){R<T> r = new R<>();
//        r.success = true;r.status = 200;r.data = data;r.message = msg;r.time = DateTime.now();return r;}/*** 错误result* @param msg* @param status* @param <T>* @return*/public static <T> R<T> error(String msg,int status){R<T> r = new R<>();
//        r.success = false;r.status = status;r.message = msg;r.time = DateTime.now();return r;}/*** 错误result* @param msg* @param <T>* @return*/public static <T> R<T> error(String msg){R<T> r = new R<>();
//        r.success = false;r.message = msg;r.time = DateTime.now();return r;}public static <T> R<T> error(AppExceptionMsgEnum appExceptionMsg){R<T> r = new R<>();
//        r.success = false;r.status = appExceptionMsg.getStatus();r.message = appExceptionMsg.getMsg();r.time = DateTime.now();return r;}}
  • 全局异常处理器
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(value = BadCredentialsException.class)public static <T> R<T> badCredentialsException(BadCredentialsException e) throws InterruptedException {return R.error(AppExceptionMsgEnum.LOGIN_ERROR);}@ExceptionHandler(value = Exception.class)public static <T> R<T> exceptionHandle(Exception e) throws InterruptedException {if(e instanceof AppException){AppException app = (AppException) e;return R.error(app.getMsg(),app.getStatus());}return R.error(e.toString(),500);}
}
  • 自定义异常
@EqualsAndHashCode(callSuper = true)
@Data
public class AppException extends RuntimeException{private int status;private String msg;public AppException(AppExceptionMsgEnum appExceptionMsgEnum) {this.status = appExceptionMsgEnum.getStatus();this.msg = appExceptionMsgEnum.getMsg();}
}
  • 异常枚举类
public enum AppExceptionMsgEnum {//成功SUCCESS(200,"操作成功"),//失败NEED_LOGIN(401,"需要登录后操作"),NO_OPERATION_AUTH(403,"无权限操作"),USERNAME_EXIST(501,"用户名已存在"),PHONE_NUMBER_EXITS(502,"手机号已存在"),EMAIL_EXIST(503,"邮箱已存在"),REQUIRED_USERNAME(504,"必须填写用户名"),LOGIN_ERROR(505," 用户名或密码错误"),WRONG_PAGE_PARAM(506,"wrong page param"),CONTENT_NOT_NULL(507,"评论内容不能为空"),FILENAME_ERROR(508,"上传文件错误"),ONLY_UPDATE_SELF(509,"只能修改自己的信息"),SERVER_ERROR(500,"SERVER ERROR");private int status;private String msg;AppExceptionMsgEnum(int status, String msg) {this.status = status;this.msg = msg;}public int getStatus() {return status;}public String getMsg() {return msg;}
}

例如:

  • API
  • 支持模型类型

小结

  • SpringSecurity5.7.0之前

    • 常见的 Spring HTTP Security 配置类都会继承一个 WebSecurityConfigureAdapter 类。
  • 从 5.7.0-M2 起,WebSecurityConfigureAdapter 被废弃了,不推荐使用。

    • 组件化开始,更加灵活。
  • 基础认证功能完成。完结撒花!!
    在这里插入图片描述

相关文章:

spring |Spring Security安全框架 —— 认证流程实现

文章目录 开头简介环境搭建入门使用1、认证1、实体类2、Controller层3、Service层3.1、接口3.2、实现类3.3、实现类&#xff1a;UserDetailsServiceImpl 4、Mapper层3、自定义token认证filter 注意事项小结 开头 Spring Security 官方网址&#xff1a;Spring Security官网 开…...

Django+vue自动化测试平台---正式开源!!!

自动化测试&#xff1a;接口、Web UI 与 App 的全面探索 在此郑重声明&#xff1a;本文内容未经本人同意&#xff0c;不得随意转载。若有违者&#xff0c;必将追究其法律责任。同时&#xff0c;禁止对相关源码进行任何形式的售卖行为&#xff0c;本内容仅供学习使用。 Git 地…...

电子电气架构 --- 智能网联汽车未来是什么样子?

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...

docker安装elasticsearch(es)+kibana

目录 docker安装elasticsearch 一.准备工作 1.打开docker目录 2.创建elasticsearch目录 3.打开elasticsearch目录 4.拉取elasticsearch镜像 5.检查镜像 二.挂载目录 1.创建数据挂载目录 2.创建配置挂载目录 3.创建插件挂载目录 4.权限授权 三.编辑配置 1.打开con…...

大厂面试真题-说说redis的雪崩、击穿和穿透

缓存雪崩、击穿、穿透是缓存系统中常见的三种问题&#xff0c;它们都会对系统的性能和稳定性造成严重影响。以下是对这三种问题的详细解释以及相应的解决方案&#xff1a; 一、缓存雪崩 问题解释&#xff1a; 缓存雪崩指的是因为某些原因导致缓存中大量的数据同时失效或过期…...

【Spring】获取Cookie和Session(@CookieValue()和@SessionAttribute())

获取 Cookie 传统获取 Cookie 这是没有 Spring 的时候&#xff0c;用 Servlet 来获取&#xff08;获取所有的 Cookie&#xff09; Spring MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;也是在 Servlet 的基础上实现的 RequestMapping("/getcookie") …...

【C++打怪之路Lv8】-- string类

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持…...

【JS】node.js压缩文件的方式

在 Node.js 中&#xff0c;有多种方法可以压缩文件。以下是几种常见的压缩方式及其对应的代码示例&#xff1a; 使用 archiver 压缩成 ZIP 文件使用 zlib 压缩成 GZIP 文件使用 tar 压缩成 TAR 文件 1. 使用 archiver 压缩成 ZIP 文件 archiver 是一个功能强大的库&#xff…...

2024免费mac苹果电脑清理垃圾软件CleanMyMac X4.15.8

对于苹果电脑用户来说&#xff0c;设备上积累的垃圾文件可能会导致存储空间变得紧张&#xff0c;影响电脑的性能和使用体验。尤其是那些经常下载和安装新应用、编辑视频或处理大量照片的用户&#xff0c;更容易感受到存储空间的压力。面对这种情况&#xff0c;寻找一种有效的苹…...

MPA-SVM多变量回归预测|海洋捕食者优化算法-支持向量机|Matalb

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…...

【uni-app】HBuilderX安装uni-ui组件

目录 1、官网找到入口 2、登录帐号 3、打开HuilderX 4、选择要应用的项目 5、查看是否安装完成 6、按需安装 7、安装完毕要重启 8、应用 前言&#xff1a;uniapp项目使用uni-ui组件方式很多&#xff0c;有npm安装等&#xff0c;或直接创建uni-ui项目&#xff0c;使用un…...

ROS2 通信三大件之动作 -- Action

通信最后一个&#xff0c;也是不太容易理解的方式action&#xff0c;复杂且重要 1、创建action数据结构 创建工作空间和模块就不多说了 在模块 src/action_moudle/action/Counter.action 下创建文件 Counter.action int32 target # Goal: 目标 --- int32 current_value…...

大数据治理:构建数据驱动的智能决策体系

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

k8s微服务

一 、什么是微服务 用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f;需要通过微服务暴漏出去后才能被访问 Service是一组提供相同服务的Pod对外开放的接口。 借助Service&#xff0c;应用可以实现服务发现和负载均衡。 service默认只支持4层负载均…...

【Java】Java 的反射机制(一):反射概述

Java 的反射机制&#xff08;一&#xff09;&#xff1a;反射概述 1.反射概述1.1 静态语言 / 动态语言1.1.1 动态语言1.1.2 静态语言 1.2 Java Reflection1.3 Java 反射机制提供的功能1.4 反射的优点和缺陷1.5 反射相关的主要 API1.6 代码示例 2.Class 类2.1 什么是 Class 类2.…...

Monorepo pnpm 模式管理多个 web 项目

Monorepo pnpm 模式管理多个 web 项目 Monorepo pnpm 模式管理多个 web 项目项目地址git flow 工作流程pnpm workspace.npmrc初始化项目架构引入Husky规范git提交配置eslint和prettiereslint 配置prettier 配置 配置lint-staged创建项目创建shared项目全局安装 vue在 packages …...

2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,看是有点意料之外,其实也在情理之中。

近日&#xff0c;2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者&#xff0c;这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家&#xff0c;如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…...

《深入理解 C++策略模式的变体:编程灵活性的新维度》

在 C编程的广阔领域中&#xff0c;设计模式起着至关重要的作用&#xff0c;它们为软件架构提供了可复用的解决方案。其中&#xff0c;策略模式是一种非常强大的设计模式&#xff0c;它允许算法的行为在运行时根据不同的策略进行改变。而策略模式的变体则进一步扩展了其灵活性和…...

一起体验AI动手实验,OceanBase 2024 年度发布会精彩预告

2024年OceanBase年度发布会将于10月23日在北京望京凯悦酒店举行。此次大会围绕“不止于记录”的主题&#xff0c;共同探讨当前数据库领域的前沿话题&#xff0c;包含主论坛、分论坛、AI 动手实训营、开源技术交流会等多个环节&#xff0c;诚邀全国各地的企业和开发者共同参与&a…...

Download Vmware Fusion (free for person)

1. web link ProductFiles - Support Portal - Broadcom support portal 2. Register user (Required) use your email to register a account 3. login and download note: the username is the email name....

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...