本文言简意赅,需要有一定的Java编程基础,说再多也不如直接撸代码,文末附SpringSecurity + JWT Demo和Github开源项目 mall-tiny 完成实现方案以供参考。直接看代码有疑惑的同学推荐两个B站免费的教学视频:
尚硅谷SpringSecurity框架教程(spring security源码剖析从入门到精通)_哔哩哔哩_bilibili
SpringSecurity框架教程-SpringSecurity+JWT实现项目级前端分离认证授权-B站最通俗易懂的SpringSecurity课程_哔哩哔哩_bilibili
Spring Security是一款可定制的身份验证和访问控制框架,是Spring应用程序的标准安全框架。其核心就是一组过滤器链。
Spring Security精简版过滤器链图
刚入门只需要了解三个比较重要的过滤器即可:
1.FilterSecurityInterceptor:方法级权限过滤器,位于过滤器链最低端
2.ExceptionTranslationFilter:异常过滤器,用来处理在认证授权过程中抛出的异常
3.UsernamePasswordAuthenticationFilter:对/login的post请求做拦截,校验表单中的用户名和密码
认证流程图:
完整调用链:官网地址:Architecture :: Spring Security
ChannelProcessingFilter
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
CsrfFilter
LogoutFilter
OAuth2AuthorizationRequestRedirectFilter
Saml2WebSsoAuthenticationRequestFilter
X509AuthenticationFilter
AbstractPreAuthenticatedProcessingFilter
CasAuthenticationFilter
OAuth2LoginAuthenticationFilter
Saml2WebSsoAuthenticationFilter
UsernamePasswordAuthenticationFilter
OpenIDAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
ConcurrentSessionFilter
DigestAuthenticationFilter
BearerTokenAuthenticationFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
JaasApiIntegrationFilter
RememberMeAuthenticationFilter
AnonymousAuthenticationFilter
OAuth2AuthorizationCodeGrantFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
SwitchUserFilter
准备工作非常简单,创建一个springboot项目,引入Spring Security依赖
org.springframework.boot
spring-boot-starter-security
随便写一个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 Transfer
Source Server : localhost
Source Server Version : 50719
Source Host : localhost:3306
Source Database : mall_tiny
Target Server Type : MYSQL
Target Server Version : 50719
File Encoding : 65001
Date: 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', '[email protected]', '测试账号', 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', '[email protected]', '系统管理员', '系统管理员', '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', '[email protected]', '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, '[email protected]', '商品管理员', '只有商品权限', '2020-02-07 16:15:08', null, '1');
INSERT INTO `ums_admin` VALUES ('7', 'orderAdmin', '$2a$10$UqEhA9UZXjHHA3B.L9wNG.6aerrBjC6WHTtbv1FdvYPUI.7lkL6E.', null, '[email protected]', '订单管理员', '只有订单管理权限', '2020-02-07 16:15:50', null, '1');
INSERT INTO `ums_admin` VALUES ('10', 'ceshi', '$2a$10$RaaNo9CC0RSms8mc/gJpCuOWndDT4pHH0u5XgZdAAYFs1Uq4sOPRi', null, '[email protected]', '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前端,开箱即用。