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

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

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

普通用户访问,失败

管理员访问,成功

相关推荐

Let’s Encrypt免费搭建HTTPS网站

HTTPS(全称:HyperTextTransferProtocoloverSecureSocketLayer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入...

使用Nginx配置TCP负载均衡(nginx tcp负载)

假设Kubernetes集群已经配置好,我们将基于CentOS为Nginx创建一个虚拟机。以下是实验种设置的详细信息:Nginx(CenOS8Minimal)-192.168.1.50Kube...

Nginx负载均衡及支持HTTPS与申请免费SSL证书

背景有两台minio文件服务器已做好集群配置,一台是192.168.56.41:9000;另一台是192.168.56.42:9000。应用程序通过Nginx负载均衡调用这两台minio服务,减轻单点...

HTTPS配置实战(https配置文件)

原因现在网站使用HTTPS是规范操作之一,前些日子买了腾讯云服务,同时申请了域名http://www.asap2me.top/,目前该域名只支持HTTP,想升级为HTTPS。关于HTTPS的链接过程大...

只有IP地址没有域名实现HTTPS访问方法

一般来说,要实现HTTPS,得有个注册好的域名才行。但有时候呢,咱只有服务器的IP地址,没注册域名,这种特殊情况下,也能照样实现HTTPS安全访问,按下面这些步骤来就行:第一步,先确认公网...

超详解:HTTPS及配置Django+HTTPS开发环境

众所周知HTTP协议是以TCP协议为基石诞生的一个用于传输Web内容的一个网络协议,在“网络分层模型”中属于“应用层协议”的一种。在这里我们并不研究该协议标准本身,而是从安全角度去探究使用该协议传输数...

Godaddy购买SSL之后Nginx配置流程以及各种错误的解决

完整流程:参考地址:https://sg.godaddy.com/zh/help/nginx-generate-csrs-certificate-signing-requests-3601生成NGI...

Nginx从安装到高可用,一篇搞定(nginx安装与配置详解)

一、Nginx安装1、去官网http://nginx.org/下载对应的nginx包,推荐使用稳定版本2、上传nginx到linux系统3、安装依赖环境(1)安装gcc环境yuminstallgc...

阿里云免费证书申请,配置安装,使用tomcat,支持http/https访问

参数说明商品类型默认已选择云盾证书服务(无需修改)。云盾证书服务类型SSL证书服务的类型。默认已选择云盾SSL证书(无需修改),表示付费版SSL证书。如果您需要免费领取或付费扩容DV单域名证书【免费试...

你试过两步实现Nginx的规范配置吗?极速生成Nginx配置小工具

NGINX是一款轻量级的Web服务器,最强大的功能之一是能够有效地提供HTML和媒体文件等静态内容。NGINX使用异步事件驱动模型,在负载下提供可预测的性能。是当下最受欢迎的高性能的Web...

从零开始搭建HTTPS服务(搭建https网站)

搭建HTTPS服务的最初目的是为了开发微信小程序,因为wx.request只允许发起HTTPS请求,并且还必须和指定的域名进行网络通信。要从零开始搭建一个HTTPS的服务需要下面4...

群晖NAS使用官网域名和自己的域名配置SSL实现HTTPS访问

安全第一步,群晖NAS使用官网域名和自己的域名配置SSL实现HTTPS访问【新手导向】NAS本质还是一个可以随时随地访问的个人数据存储中心,我们在外网访问的时候,特别是在公网IP下,其实会面临着很多安...

让网站快速升级HTTPS协议提高安全性

为什么用HTTPS网络安全越来越受到重视,很多互联网服务网站,都已经升级改造为https协议。https协议下数据包是ssl/tcl加密的,而http包是明文传输。如果请求一旦被拦截,数据就会泄露产生...

用Https方式访问Harbor-1.9版本(https访问流程)

我上周在头条号写过一篇原创文章《Docker-Harbor&Docker-kitematic史上最详细双系统配置手册》,这篇算是它的姊妹篇吧。这篇文章也将用到我在头条写的另一篇原创文章的...

如何启用 HTTPS 并配置免费的 SSL 证书

在Linux服务器上启用HTTPS并配置免费的SSL证书(以Let'sEncrypt为例)可以通过以下步骤完成:---###**一、准备工作**1.**确保域名已解析**...

取消回复欢迎 发表评论: