当前位置: 代码迷 >> 综合 >> 单体架构下的认证授权方案 - SpringSecurity + JWT
  详细解决方案

单体架构下的认证授权方案 - SpringSecurity + JWT

热度:23   发布时间:2023-10-28 09:00:23.0

本文言简意赅,需要有一定的Java编程基础,说再多也不如直接撸代码,文末附SpringSecurity + JWT Demo和Github开源项目 mall-tiny 完成实现方案以供参考。直接看代码有疑惑的同学推荐两个B站免费的教学视频:
尚硅谷SpringSecurity框架教程(spring security源码剖析从入门到精通)_哔哩哔哩_bilibili

SpringSecurity框架教程-SpringSecurity+JWT实现项目级前端分离认证授权-B站最通俗易懂的SpringSecurity课程_哔哩哔哩_bilibili

一、Spring Security简介

Spring Security是一款可定制的身份验证和访问控制框架,是Spring应用程序的标准安全框架。其核心就是一组过滤器链。

Spring Security精简版过滤器链图

刚入门只需要了解三个比较重要的过滤器即可:

1.FilterSecurityInterceptor:方法级权限过滤器,位于过滤器链最低端

2.ExceptionTranslationFilter:异常过滤器,用来处理在认证授权过程中抛出的异常

3.UsernamePasswordAuthenticationFilter:对/login的post请求做拦截,校验表单中的用户名和密码

认证流程图:

完整调用链:官网地址:Architecture :: Spring Security

ChannelProcessingFilterWebAsyncManagerIntegrationFilterSecurityContextPersistenceFilterHeaderWriterFilterCorsFilterCsrfFilterLogoutFilterOAuth2AuthorizationRequestRedirectFilterSaml2WebSsoAuthenticationRequestFilterX509AuthenticationFilterAbstractPreAuthenticatedProcessingFilterCasAuthenticationFilterOAuth2LoginAuthenticationFilterSaml2WebSsoAuthenticationFilterUsernamePasswordAuthenticationFilterOpenIDAuthenticationFilterDefaultLoginPageGeneratingFilterDefaultLogoutPageGeneratingFilterConcurrentSessionFilterDigestAuthenticationFilterBearerTokenAuthenticationFilterBasicAuthenticationFilterRequestCacheAwareFilterSecurityContextHolderAwareRequestFilterJaasApiIntegrationFilterRememberMeAuthenticationFilterAnonymousAuthenticationFilterOAuth2AuthorizationCodeGrantFilterSessionManagementFilterExceptionTranslationFilterFilterSecurityInterceptorSwitchUserFilter

二、准备工作

准备工作非常简单,创建一个springboot项目,引入Spring Security依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

随便写一个Controller中的方法,然后启动项目直接调用,会发现地址栏自动跳转到了/login,并提示输入用户名和密码

 默认用户名user,密码在控制台里打印

 输入后可以发现Controller里的方法已经可以调用,原理其实就是Spring Security包内提供了一系列的默认实现,包括默认用户名密码,默认登录页,默认登录接口等,然后利用SpringBoot的自动装配依次读取并配置。

三、我们要对框架原默认流程做哪些修改

ok,准备工作完成之后,我们思考一个问题,究竟我们要对框架原默认流程做哪些修改?

首先Spring Security默认用户密码是系统生成,这肯定需要改成从数据库中读取。

其次API层面的权限定制化需要我们自己去实现

再有虽然是单体项目,但目前业内大多也都是前后端分离,那么Spring Security原有的session认证传递就不是很好用(前后端分离还需要解决跨域session传递问题,如果后期项目体量变大做了分布式还需要去解决分布式session的问题),所以需要换成业内推崇的JWT(Token)方案。

四、动手实现

登录时序图:

 将默认生成的用户名和密码改成查库获取:

新建配置类定制化Spring Security:

 自定义JWT拦截器:

 登录接口代码片段:

权限认证接口测试:主要还是@PreAuthorize注解,此处应该将权限和接口url的匹配关系写入数据库内,动态从数据库中查询获取,mall-tiny项目有完整实现

 数据库SQL:

/*
Navicat MySQL Data TransferSource Server         : localhost
Source Server Version : 50719
Source Host           : localhost:3306
Source Database       : mall_tinyTarget Server Type    : MYSQL
Target Server Version : 50719
File Encoding         : 65001Date: 2020-08-24 14:06:42
*/SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for ums_admin
-- ----------------------------
DROP TABLE IF EXISTS `ums_admin`;
CREATE TABLE `ums_admin` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(64) DEFAULT NULL,`password` varchar(64) DEFAULT NULL,`icon` varchar(500) DEFAULT NULL COMMENT '头像',`email` varchar(100) DEFAULT NULL COMMENT '邮箱',`nick_name` varchar(200) DEFAULT NULL COMMENT '昵称',`note` varchar(500) DEFAULT NULL COMMENT '备注信息',`create_time` datetime DEFAULT NULL COMMENT '创建时间',`login_time` datetime DEFAULT NULL COMMENT '最后登录时间',`status` int(1) DEFAULT '1' COMMENT '帐号启用状态:0->禁用;1->启用',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COMMENT='后台用户表';-- ----------------------------
-- Records of ums_admin
-- ----------------------------
INSERT INTO `ums_admin` VALUES ('1', 'test', '$2a$10$NZ5o7r2E.ayT2ZoxgjlI.eJ6OEYqjH7INR/F.mXDbjZJi9HF0YCVG', 'http://macro-oss.oss-cn-shenzhen.aliyuncs.com/mall/images/20180607/timg.jpg', 'test@qq.com', '测试账号', null, '2018-09-29 13:55:30', '2018-09-29 13:55:39', '1');
INSERT INTO `ums_admin` VALUES ('3', 'admin', '$2a$10$rNGcsXjfhVgJ9wJwOoaalO3XJ5GRTZWVFVFA9e0kPKb/YaOBgwtk.', 'http://macro-oss.oss-cn-shenzhen.aliyuncs.com/mall/images/20180607/timg.jpg', 'admin@163.com', '系统管理员', '系统管理员', '2018-10-08 13:32:47', '2019-04-20 12:45:16', '1');
INSERT INTO `ums_admin` VALUES ('4', 'macro', '$2a$10$Bx4jZPR7GhEpIQfefDQtVeS58GfT5n6mxs/b4nLLK65eMFa16topa', 'string', 'macro@qq.com', 'macro', 'macro专用', '2019-10-06 15:53:51', '2020-02-03 14:55:55', '1');
INSERT INTO `ums_admin` VALUES ('6', 'productAdmin', '$2a$10$6/.J.p.6Bhn7ic4GfoB5D.pGd7xSiD1a9M6ht6yO0fxzlKJPjRAGm', null, 'product@qq.com', '商品管理员', '只有商品权限', '2020-02-07 16:15:08', null, '1');
INSERT INTO `ums_admin` VALUES ('7', 'orderAdmin', '$2a$10$UqEhA9UZXjHHA3B.L9wNG.6aerrBjC6WHTtbv1FdvYPUI.7lkL6E.', null, 'order@qq.com', '订单管理员', '只有订单管理权限', '2020-02-07 16:15:50', null, '1');
INSERT INTO `ums_admin` VALUES ('10', 'ceshi', '$2a$10$RaaNo9CC0RSms8mc/gJpCuOWndDT4pHH0u5XgZdAAYFs1Uq4sOPRi', null, 'ceshi@qq.com', 'ceshi', null, '2020-03-13 16:23:30', null, '1');

默认账号admin/admin

五、项目工程地址

博主DEMO地址:https://github.com/L1021204735/SpringSecurity-JWT

mall-tiny项目地址:GitHub - macrozheng/mall-tiny: mall-tiny是一款基于SpringBoot+MyBatis-Plus的快速开发脚手架,拥有完整的权限管理功能,可对接Vue前端,开箱即用。

  相关解决方案