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

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

nanshan 2024-10-30 02:57 6 浏览 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.测试

普通用户访问,失败

管理员访问,成功

相关推荐

F5负载均衡器如何通过irules实现应用的灵活转发?

F5是非常强大的商业负载均衡器。除了处理性能强劲,以及高稳定性之外,F5还可以通过irules编写强大灵活的转发规则,实现web业务的灵活应用。irules是基于TCL语法的,每个iRules必须包含...

映射域名到NAS

前面介绍已经将域名映射到家庭路由器上,现在只需要在路由器上设置一下端口转发即可。假设NAS在内网的IP是192.168.1.100,NAS管理端口2000.你的域名是www.xxx.com,配置外部端...

转发(Forward)和重定向(Redirect)的区别

转发是服务器行为,重定向是客户端行为。转发(Forward)通过RequestDispatcher对象的forward(HttpServletRequestrequest,HttpServletRe...

SpringBoot应用中使用拦截器实现路由转发

1、背景项目中有一个SpringBoot开发的微服务,经过业务多年的演进,代码已经累积到令人恐怖的规模,亟需重构,将之拆解成多个微服务。该微服务的接口庞大,调用关系非常复杂,且实施重构的人员大部分不是...

公司想搭建个网站,网站如何进行域名解析?

域名解析是将域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。IP地址是网络上标识站点的数字地址,为方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转...

域名和IP地址什么关系?如何通过域名解析IP?

一般情况下,访客通过域名和IP地址都能访问到网站,那么两者之间有什么关系吗?本文中科三方针对域名和IP地址的关系和区别,以及如何实现域名与IP的绑定做下介绍。域名与IP地址之间的关系IP地址是计算机的...

分享网站域名301重定向的知识

网站域名做301重定向操作时,一般需要由专业的技术来协助完成,如果用户自己在维护,可以按照相应的说明进行操作。好了,下面说说重点,域名301重定向的操作步骤。首先,根据HTTP协议,在客户端向服务器发...

NAS外网到底安全吗?一文看懂HTTP/HTTPS和SSL证书

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:可爱的小cherry搭好了NAS,但是不懂做好网络加密,那么隐私泄露也会随时发生!大家好,这里是Cherry,喜爱折腾、玩数码,热衷于分享数...

ForwardEmail免费、开源、加密的邮件转发服务

ForwardEmail是一款免费、加密和开源的邮件转发服务,设置简单只需4步即可正常使用,通过测试来看也要比ImprovMX好得多,转发近乎秒到且未进入垃圾箱(仅以Mailbox.org发送、Out...

使用CloudFlare进行域名重定向

当网站变更域名的时候,经常会使用域名重定向的方式,将老域名指向到新域名,这通常叫做:URL转发(URLFORWARDING),善于使用URL转发,对SEO来说非常有用,因为用这种方式能明确告知搜索引...

要将端口5002和5003通过Nginx代理到一个域名上的操作笔记

要将端口5002和5003通过Nginx代理到域名www.4rvi.cn的不同路径下,请按照以下步骤配置Nginx:步骤说明创建或编辑Nginx配置文件通常配置文件位于/etc/nginx/sites...

SEO浅谈:网站域名重定向的三种方式

在大多数情况下,我们输入网站访问网站的时候,很难发现www.***.com和***.com的区别,因为一般的网站主,都会把这两个域名指向到同一网站。但是对于网站运营和优化来说,www.***.com和...

花生壳出现诊断域名与转发服务器ip不一致的解决办法

出现诊断域名与转发服务器ip不一致您可以:1、更改客户端所处主机的drs为223.5.5.5备用dns为119.29.29.29;2、在windows上进入命令提示符输入ipconfig/flush...

涨知识了!带你认识什么是域名

1、什么是域名从技术角度来看,域名是在Internet上解决IP地址对应的一种方法。一个完整的域名由两个或两个以上部分组成,各部分之间用英文的句号“.”来分隔。如“abc.com”。其中“com”称...

域名被跳转到其他网站是怎么回事

当你输入域名时被跳转到另一个网站,这可能是由几种原因造成的:一、域名可能配置了域名转发服务。无论何时有人访问域名,比如.com、.top等,都会自动重定向到另一个指定的URL,这通常是在域名注册商设...

取消回复欢迎 发表评论: