百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

springsecurity实现前后端分离项目中的认证和授权

ztj100 2025-04-30 21:20 32 浏览 0 评论

以一个最基础的用户管理系统为例,要实现以下功能:

  • 用户密码加密
  • 支持通过用户名、手机号、邮箱 + 密码登录
  • 手机号登录支持短信验证码登录,邮箱登录支持邮件验证码登录
  • 用户登录成功后,之后的请求通过JWT令牌验证身份信息
  • 对于需要保护的接口,进行权限检查

准备工作

1.设计表,并填充数据

使用典型的RBAC模型,共有5张表:

用户表: t_ums_user

角色表: t_ums_role

用户-角色关系表: t_ums_user_role

权限表: t_permission

角色-权限关系表: t_role_permission

2.创建springboot工程,并创建启动类

springboot版本为2.5.14

添加依赖

创建启动类

3.创建数据表对应的实体类

省略每个实体的getter和setter方法

用户

角色

用户-角色

权限

角色-权限

4.集成mybatis


mybatis-spring-boot-starter版本为2.2.2,mysql-connector-java版本为8.0.27

添加mybatis和mysql依赖

在application.yml文件中配置数据源,以及mybatis相关的配置

5.创建每个实体对应的Controller,Mapper接口及其XML映射文件

这里去掉了Service层

5.1 实现发送验证码接口

Validator类:声明用于校验用户名、手机号、邮箱的正则表达式

Cache类:用HashMap模拟一个缓存数据库(实际生产中使用Redis等高性缓存能数据库)

VerifyCodeController:定义发送验证码接口

这里并没有真的去发送验证码,只在控制台中输出。

测试接口

控制台中输出了验证码

5.2 实现增删改查方法

这里只列出必要的增删改查方法

Mapper 接口定义如下,只有UMSUserMapper接口中定义了几个方法

Mapper XML映射文件如下

5.3 实现控制器

作为示例,只在UMSUserController中定义了3个控制器方法:用户注册、查询用户信息、查询用户列表

其中,用户注册方法定义如下

密码加密部分需要用到springsecurity中的api,后续完成

6.引入springsecurity

添加springsecurity依赖

创建一个配置类,用于自定义security

身份认证

配置请求资源拦截规则

  • 获取验证码接口,放行全部
  • 注册接口,放行全部
  • 查看用户信息接口,需要进行身份认证
  • 其它的请求,全部拒绝访问

密码加密

只需要在spring容器中注入一个PasswordEncoder即可

完成注册接口中密码加密部分的代码

测试用户注册接口

顺便把用户表中其它用户的密码也加密一下,写个测试用例

自定义认证数据源

springsecurity默认从内存中获取用户信息(
InMemoryUserDetailsManager),现在需要从数据库中查询用户信息,所以需要自定义。

1.定义UserDetails接口的实现类,封装用户信息

获取权限信息的getAuthoities方法留到权限控制一节中完成。

2.定义UserDetailsService接口的实现类,定义获取用户信息的方法

UserDetails接口默认只声明了根据用户名获取用户信息的方法,这里需要支持用户名、手机号、邮箱登录,所以,共定义了3个获取用户信息的方法

实现密码登录

springsecurity默认使用用户名+密码的方式进行登录认证,我们要同时支持用户名、手机号、邮箱3中账号,需要进行自定义。

0.定义2个异常类,代表在手机号码和邮箱不存在异常

1.定义Authentication认证信息存储类

参考
UsernamePasswordAuthenticationToken类,继承抽象类
AbstractAuthenticationToken,负责存储认证以及权限信息

2.定义登录认证Filter

参考
UsernamePasswordAuthenticationFilter类,继承抽象类
AbstractAuthenticationProcessingFilter,负责从请求中获取认证信息,封装为Authentication对象,然后使用AuthenticationManager去进行认证,具体的验证逻辑由AuthenticationProvider负责

3.定义登录认证Provider

参考
AbstractUserDetailsAuthenticationProvider类,实现接口AuthenticationProvider,负责进行具体的认证

4.定义认证成功、认证失败Handler

认证成功处理器实现接口
AuthenticationSuccessHandler

认证失败处理器实现接口
AuthenticationFailureHandler,认证失败抛出的AuthenticationException异常作为参数传入

5.配置

6.测试

分别使用用户名、手机号、邮箱 + 密码进行登录。

登录成功

登录失败: 用户名不存在

登录失败: 账号格式错误

登录失败: 密码错误

实现验证码登录

验证码登录与密码登录差不多,只要把校验密码改为校验验证码即可。

1.定义Authentication认证信息存储类

2.定义登录认证Filter

3.定义登录认证Provider

4.配置

注入Filter和Provider Bean

配置Filter和Provider

5.测试

先获取一下手机验证码,使用手机号+验证码登录

再获取一下邮箱验证码,使用邮箱+验证码登录

实现JWT认证

注意:网上很多教程将登录后的用户信息存储的Redis中,这其实是错误的做法。JWT本身就可以进行信息交换,并且其初衷就用于实现无状态的身份认证,如果使用Redis存储用户信息,本质上是自己又实现了一套Session机制。

采用jwt实现身份认证与信息交换,主要分为2个步骤:

  • 1.客户端请求登录接口,认证通过后,服务端生成jwt令牌,并返回给客户端
  • 2.客户端请求其它需要认证的接口时,携带token,服务端验证token是否有效,以此决定是否放行

0.生成和解析jwt令牌

这里使用开源库jjwt,github:
https://github.com/jwtk/jjwt#install

添加依赖

在application配置文件中,定义2个配置项,并创建响应的Properties类。其中:

  • secret-key表示jwt密钥,使用接下来定义的JWT工具类生成
  • expiration表示令牌过期时间

创建JWT工具类

1.登录成功后,生成jwt令牌并返回给客户端

修改认证成功处理器

测试

2.定义过滤器,验证jwt令牌

3.定义认证异常处理器

实现AuthenticationEntryPoint接口

4.配置

注入Filter Bean

将JWT Filter添加到过滤器链,并配置认证异常处理器

5.测试

访问用户信息接口

不带token时,认证失败

带上token,访问成功

权限控制

基本使用

1.修改自定义的UserDetails类,完善getAuthorities方法

2.定义访问拒绝异常处理器

实现AccessDeniedHandler接口

3.启用全局方法级别的访问控制

也可以在配置类中,使用基于URL资源的访问控制

4.在需要进行权限检查的控制器方法上,声明权限信息

在访问用户列表的控制器方法上,声明管理员权限

5.测试

普通用户访问,失败

管理员访问,成功

相关推荐

30天学会Python编程:16. Python常用标准库使用教程

16.1collections模块16.1.1高级数据结构16.1.2示例...

强烈推荐!Python 这个宝藏库 re 正则匹配

Python的re模块(RegularExpression正则表达式)提供各种正则表达式的匹配操作。...

Python爬虫中正则表达式的用法,只讲如何应用,不讲原理

Python爬虫:正则的用法(非原理)。大家好,这节课给大家讲正则的实际用法,不讲原理,通俗易懂的讲如何用正则抓取内容。·导入re库,这里是需要从html这段字符串中提取出中间的那几个文字。实例一个对...

Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)

实现功能:Python数据分析实战-利用正则表达式提取文本中的URL网址和邮箱...

python爬虫教程之爬取当当网 Top 500 本五星好评书籍

我们使用requests和re来写一个爬虫作为一个爱看书的你(说的跟真的似的)怎么能发现好书呢?所以我们爬取当当网的前500本好五星评书籍怎么样?ok接下来就是学习python的正确姿...

深入理解re模块:Python中的正则表达式神器解析

在Python中,"re"是一个强大的模块,用于处理正则表达式(regularexpressions)。正则表达式是一种强大的文本模式匹配工具,用于在字符串中查找、替换或提取特定模式...

如何使用正则表达式和 Python 匹配不以模式开头的字符串

需要在Python中使用正则表达式来匹配不以给定模式开头的字符串吗?如果是这样,你可以使用下面的语法来查找所有的字符串,除了那些不以https开始的字符串。r"^(?!https).*&...

先Mark后用!8分钟读懂 Python 性能优化

从本文总结了Python开发时,遇到的性能优化问题的定位和解决。概述:性能优化的原则——优化需要优化的部分。性能优化的一般步骤:首先,让你的程序跑起来结果一切正常。然后,运行这个结果正常的代码,看看它...

Python“三步”即可爬取,毋庸置疑

声明:本实例仅供学习,切忌遵守robots协议,请不要使用多线程等方式频繁访问网站。#第一步导入模块importreimportrequests#第二步获取你想爬取的网页地址,发送请求,获取网页内...

简单学Python——re库(正则表达式)2(split、findall、和sub)

1、split():分割字符串,返回列表语法:re.split('分隔符','目标字符串')例如:importrere.split(',','...

Lavazza拉瓦萨再度牵手上海大师赛

阅读此文前,麻烦您点击一下“关注”,方便您进行讨论和分享。Lavazza拉瓦萨再度牵手上海大师赛标题:2024上海大师赛:网球与咖啡的浪漫邂逅在2024年的上海劳力士大师赛上,拉瓦萨咖啡再次成为官...

ArkUI-X构建Android平台AAR及使用

本教程主要讲述如何利用ArkUI-XSDK完成AndroidAAR开发,实现基于ArkTS的声明式开发范式在android平台显示。包括:1.跨平台Library工程开发介绍...

Deepseek写歌详细教程(怎样用deepseek写歌功能)

以下为结合DeepSeek及相关工具实现AI写歌的详细教程,涵盖作词、作曲、演唱全流程:一、核心流程三步法1.AI生成歌词-打开DeepSeek(网页/APP/API),使用结构化提示词生成歌词:...

“AI说唱解说影视”走红,“零基础入行”靠谱吗?本报记者实测

“手里翻找冻鱼,精心的布局;老漠却不言语,脸上带笑意……”《狂飙》剧情被写成歌词,再配上“科目三”背景音乐的演唱,这段1分钟30秒的视频受到了无数网友的点赞。最近一段时间随着AI技术的发展,说唱解说影...

AI音乐制作神器揭秘!3款工具让你秒变高手

在音乐创作的领域里,每个人都有一颗想要成为大师的心。但是面对复杂的乐理知识和繁复的制作过程,许多人的热情被一点点消磨。...

取消回复欢迎 发表评论: