首页 > 其他分享 >Spring Security认证授权练手小项目 腾讯视频VIP权限管理功能

Spring Security认证授权练手小项目 腾讯视频VIP权限管理功能

时间:2023-01-07 14:33:16浏览次数:54  
标签:练手 INSERT Spring INTO VIP video tencent VALUES permissions


腾讯视频VIP权限管理

  • ​​1、项目功能视频演示​​
  • ​​2、需求与设计​​
  • ​​1、需求​​
  • ​​2、功能概要​​
  • ​​3、接口设计​​
  • ​​3、项目源码结构​​
  • ​​4、项目源码下载​​
  • ​​5、项目部署​​
  • ​​1、部署架构​​
  • ​​2、数据库环境准备​​
  • ​​3、redis环境准备​​
  • ​​4、Spring Boot服务准备​​
  • ​​5、nginx负载均衡准备​​
  • ​​6、nginx静态资源服务器准备​​
  • ​​6、项目介绍​​
  • ​​1、技术架构​​
  • ​​2、技术汇总​​
  • ​​7、配置数据开发​​

1、项目功能视频演示

腾讯视频VIP权限管理功能演示

2、需求与设计

1、需求

所有视频必须登录才能看。

免费角色(ROLE_free)可观看免费视频列表。

为每个用户分配一个普通会员角色(general_{username}),该角色继承免费角色,购买的视频(资源)会绑定到这个普通会员角色上。

青铜vip角色继承免费角色,并且可观看青铜vip独享视频。

白银vip角色继承青铜vip角色,并且可以观看白银vip独享视频。

可扩展角色,如黄金vip继承白银vip,铂金vip继承黄金vip,以此类推。

每个用户至少有一个与之绑定的普通会员角色,和多个vip角色。

提供一个admin角色,可管理后台(目前仅有踢人功能)。

2、功能概要

Spring Security认证授权练手小项目 腾讯视频VIP权限管理功能_java

3、接口设计

AppController 不用登录就能访问的资源

UserController 需要登录才能访问的资源

AdminController 需要admin角色才能访问的资源

CustomController 基于数据库表的动态URL权限管理

3、项目源码结构

F:.
│ pom.xml
│ readme.md

└─src
└─main
├─java
│ └─com
│ └─bobo
│ └─springbootsecurity
│ │ SpringbootSecurityApp.java
│ │
│ ├─config
│ │ CaptchaConfig.java
│ │ HttpSessionConfig.java
│ │ SessionSerializerConfig.java
│ │ SpringSessionConfig.java
│ │ WebSecurityConfig.java
│ │
│ ├─controller
│ │ AdminController.java
│ │ AppController.java
│ │ CustomController.java
│ │ UserController.java
│ │
│ ├─entity
│ │ TencentVideoPermissions.java
│ │ TencentVideoPermissionsExample.java
│ │ TencentVideoRolePermission.java
│ │ TencentVideoRolePermissionExample.java
│ │ TencentVideoRoles.java
│ │ TencentVideoRolesExample.java
│ │ TencentVideoRoleUrls.java
│ │ TencentVideoRoleUrlsExample.java
│ │ TencentVideos.java
│ │ TencentVideosExample.java
│ │ TencentVideoUserRole.java
│ │ TencentVideoUserRoleExample.java
│ │ TencentVideoUsers.java
│ │ TencentVideoUsersExample.java
│ │
│ ├─exception
│ │ CaptchaCheckException.java
│ │
│ ├─handler
│ │ CustomAuthenticationProvider.java
│ │ CustomSecurityMetadataSource.java
│ │ CustomUserDetailService.java
│ │ JsonAuthenticationFailureHandler.java
│ │ JsonAuthenticationSuccessHandler.java
│ │ MySecurityExpressionRoot.java
│ │ SecurityUser.java
│ │ VideoPermissionExpression.java
│ │
│ ├─mapper
│ │ TencentVideoPermissionsMapper.java
│ │ TencentVideoRolePermissionMapper.java
│ │ TencentVideoRolesMapper.java
│ │ TencentVideoRoleUrlsMapper.java
│ │ TencentVideosMapper.java
│ │ TencentVideoUserRoleMapper.java
│ │ TencentVideoUsersMapper.java
│ │
│ └─util
│ Result.java

└─resources
│ application.yml
│ generatorConfig.xml
│ jdbc.properties

├─mappers
│ TencentVideoPermissionsMapper.xml
│ TencentVideoRolePermissionMapper.xml
│ TencentVideoRolesMapper.xml
│ TencentVideoRoleUrlsMapper.xml
│ TencentVideosMapper.xml
│ TencentVideoUserRoleMapper.xml
│ TencentVideoUsersMapper.xml

└─static
common.js
index.html
jquery-3.4.1.js
login.html
redirect.html

4、项目源码下载


5、项目部署

注意:以下部署教程均在windows操作系统上进行。

1、部署架构

Spring Security认证授权练手小项目 腾讯视频VIP权限管理功能_springsecurity_02


避坑:要在服务节点上通过Spring Security配置跨域,负载均衡nginx不需要配置跨域,否则请求会出现某些错误。

2、数据库环境准备

数据库初始化脚本:

CREATE TABLE t_tencent_video_users (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
username varchar(255) DEFAULT NULL,
password varchar(255) DEFAULT NULL,
sex varchar(255) DEFAULT NULL,
birthday date DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频用户表';

CREATE TABLE t_tencent_video_user_role (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id int(10) DEFAULT NULL,
role_id int(10) DEFAULT NULL,
expire datetime DEFAULT NULL COMMENT '有效期至',
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频用户角色关联表';

CREATE TABLE t_tencent_video_roles (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
role varchar(255) DEFAULT NULL COMMENT '角色标识',
role_name varchar(255) DEFAULT NULL COMMENT '角色名称',
parent_role_id int(10) DEFAULT NULL COMMENT '父角色',
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频角色表';

CREATE TABLE t_tencent_video_role_permission (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
role_id int(10) DEFAULT NULL,
permission_id int(10) DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频角色权限关联表';

CREATE TABLE t_tencent_video_permissions (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
permission varchar(255) DEFAULT NULL COMMENT '权限标识',
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频权限表';

CREATE TABLE t_tencent_videos (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
video_name varchar(255) DEFAULT NULL,
video_permission varchar(255) DEFAULT NULL COMMENT '视频权限标识',
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频视频表';

CREATE TABLE t_tencent_video_role_urls (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
role_id int(10) DEFAULT NULL,
url varchar(255) DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频动态URL权限管理表';


-- 初始化数据
-- ----------------------------
-- Records of t_tencent_video_permissions
-- ----------------------------
INSERT INTO t_tencent_video_permissions VALUES (1, 'video_86xiyou:*');
INSERT INTO t_tencent_video_permissions VALUES (2, 'video_86xiyou:comment');
INSERT INTO t_tencent_video_permissions VALUES (3, 'video_86xiyou:download');
INSERT INTO t_tencent_video_permissions VALUES (4, 'video_86xiyou:read');
INSERT INTO t_tencent_video_permissions VALUES (5, 'video_daomu:*');
INSERT INTO t_tencent_video_permissions VALUES (6, 'video_daomu:comment');
INSERT INTO t_tencent_video_permissions VALUES (7, 'video_daomu:download');
INSERT INTO t_tencent_video_permissions VALUES (8, 'video_daomu:read');
INSERT INTO t_tencent_video_permissions VALUES (9, 'video_first:*');
INSERT INTO t_tencent_video_permissions VALUES (10, 'video_first:comment');
INSERT INTO t_tencent_video_permissions VALUES (11, 'video_first:download');
INSERT INTO t_tencent_video_permissions VALUES (12, 'video_first:read');
INSERT INTO t_tencent_video_permissions VALUES (13, 'video_gong:*');
INSERT INTO t_tencent_video_permissions VALUES (14, 'video_gong:comment');
INSERT INTO t_tencent_video_permissions VALUES (15, 'video_gong:download');
INSERT INTO t_tencent_video_permissions VALUES (16, 'video_gong:read');
INSERT INTO t_tencent_video_permissions VALUES (17, 'video_hu_shediao:*');
INSERT INTO t_tencent_video_permissions VALUES (18, 'video_hu_shediao:comment');
INSERT INTO t_tencent_video_permissions VALUES (19, 'video_hu_shediao:download');
INSERT INTO t_tencent_video_permissions VALUES (20, 'video_hu_shediao:read');
INSERT INTO t_tencent_video_permissions VALUES (21, 'video_huang_dragon:*');
INSERT INTO t_tencent_video_permissions VALUES (22, 'video_huang_dragon:comment');
INSERT INTO t_tencent_video_permissions VALUES (23, 'video_huang_dragon:download');
INSERT INTO t_tencent_video_permissions VALUES (24, 'video_huang_dragon:read');
INSERT INTO t_tencent_video_permissions VALUES (25, 'video_huaqiangu:*');
INSERT INTO t_tencent_video_permissions VALUES (26, 'video_huaqiangu:comment');
INSERT INTO t_tencent_video_permissions VALUES (27, 'video_huaqiangu:download');
INSERT INTO t_tencent_video_permissions VALUES (28, 'video_huaqiangu:read');
INSERT INTO t_tencent_video_permissions VALUES (29, 'video_langya:*');
INSERT INTO t_tencent_video_permissions VALUES (30, 'video_langya:comment');
INSERT INTO t_tencent_video_permissions VALUES (31, 'video_langya:download');
INSERT INTO t_tencent_video_permissions VALUES (32, 'video_langya:read');
INSERT INTO t_tencent_video_permissions VALUES (33, 'video_lovehouse:*');
INSERT INTO t_tencent_video_permissions VALUES (34, 'video_lovehouse:comment');
INSERT INTO t_tencent_video_permissions VALUES (35, 'video_lovehouse:download');
INSERT INTO t_tencent_video_permissions VALUES (36, 'video_lovehouse:read');
INSERT INTO t_tencent_video_permissions VALUES (37, 'video_new3country:*');
INSERT INTO t_tencent_video_permissions VALUES (38, 'video_new3country:comment');
INSERT INTO t_tencent_video_permissions VALUES (39, 'video_new3country:download');
INSERT INTO t_tencent_video_permissions VALUES (40, 'video_new3country:read');
INSERT INTO t_tencent_video_permissions VALUES (41, 'video_shenhua:*');
INSERT INTO t_tencent_video_permissions VALUES (42, 'video_shenhua:comment');
INSERT INTO t_tencent_video_permissions VALUES (43, 'video_shenhua:download');
INSERT INTO t_tencent_video_permissions VALUES (44, 'video_shenhua:read');
INSERT INTO t_tencent_video_permissions VALUES (45, 'video_shuihu:*');
INSERT INTO t_tencent_video_permissions VALUES (46, 'video_shuihu:comment');
INSERT INTO t_tencent_video_permissions VALUES (47, 'video_shuihu:download');
INSERT INTO t_tencent_video_permissions VALUES (48, 'video_shuihu:read');
INSERT INTO t_tencent_video_permissions VALUES (49, 'video_su_yitian:*');
INSERT INTO t_tencent_video_permissions VALUES (50, 'video_su_yitian:comment');
INSERT INTO t_tencent_video_permissions VALUES (51, 'video_su_yitian:download');
INSERT INTO t_tencent_video_permissions VALUES (52, 'video_su_yitian:read');
INSERT INTO t_tencent_video_permissions VALUES (53, 'video_weizhuang:*');
INSERT INTO t_tencent_video_permissions VALUES (54, 'video_weizhuang:comment');
INSERT INTO t_tencent_video_permissions VALUES (55, 'video_weizhuang:download');
INSERT INTO t_tencent_video_permissions VALUES (56, 'video_weizhuang:read');
INSERT INTO t_tencent_video_permissions VALUES (57, 'video_wind11:*');
INSERT INTO t_tencent_video_permissions VALUES (58, 'video_wind11:comment');
INSERT INTO t_tencent_video_permissions VALUES (59, 'video_wind11:download');
INSERT INTO t_tencent_video_permissions VALUES (60, 'video_wind11:read');
INSERT INTO t_tencent_video_permissions VALUES (61, 'video_windgirl:*');
INSERT INTO t_tencent_video_permissions VALUES (62, 'video_windgirl:comment');
INSERT INTO t_tencent_video_permissions VALUES (63, 'video_windgirl:download');
INSERT INTO t_tencent_video_permissions VALUES (64, 'video_windgirl:read');
INSERT INTO t_tencent_video_permissions VALUES (65, 'video_xian3:*');
INSERT INTO t_tencent_video_permissions VALUES (66, 'video_xian3:comment');
INSERT INTO t_tencent_video_permissions VALUES (67, 'video_xian3:download');
INSERT INTO t_tencent_video_permissions VALUES (68, 'video_xian3:read');
INSERT INTO t_tencent_video_permissions VALUES (69, 'video_xianjian:*');
INSERT INTO t_tencent_video_permissions VALUES (70, 'video_xianjian:comment');
INSERT INTO t_tencent_video_permissions VALUES (71, 'video_xianjian:download');
INSERT INTO t_tencent_video_permissions VALUES (72, 'video_xianjian:read');
INSERT INTO t_tencent_video_permissions VALUES (73, 'video_xuanyuan:*');
INSERT INTO t_tencent_video_permissions VALUES (74, 'video_xuanyuan:comment');
INSERT INTO t_tencent_video_permissions VALUES (75, 'video_xuanyuan:download');
INSERT INTO t_tencent_video_permissions VALUES (76, 'video_xuanyuan:read');
INSERT INTO t_tencent_video_permissions VALUES (77, 'video_yumeng:*');
INSERT INTO t_tencent_video_permissions VALUES (78, 'video_yumeng:comment');
INSERT INTO t_tencent_video_permissions VALUES (79, 'video_yumeng:download');
INSERT INTO t_tencent_video_permissions VALUES (80, 'video_yumeng:read');
-- ----------------------------
-- Records of t_tencent_video_role_permission
-- ----------------------------
INSERT INTO t_tencent_video_role_permission VALUES (1, 1, 2);
INSERT INTO t_tencent_video_role_permission VALUES (2, 1, 4);
INSERT INTO t_tencent_video_role_permission VALUES (3, 1, 6);
INSERT INTO t_tencent_video_role_permission VALUES (4, 1, 8);
INSERT INTO t_tencent_video_role_permission VALUES (5, 2, 1);
INSERT INTO t_tencent_video_role_permission VALUES (6, 2, 5);
INSERT INTO t_tencent_video_role_permission VALUES (7, 2, 9);
INSERT INTO t_tencent_video_role_permission VALUES (8, 2, 13);
INSERT INTO t_tencent_video_role_permission VALUES (9, 2, 17);
INSERT INTO t_tencent_video_role_permission VALUES (10, 2, 21);
INSERT INTO t_tencent_video_role_permission VALUES (11, 2, 25);
INSERT INTO t_tencent_video_role_permission VALUES (12, 2, 29);
INSERT INTO t_tencent_video_role_permission VALUES (13, 3, 33);
INSERT INTO t_tencent_video_role_permission VALUES (14, 3, 37);
INSERT INTO t_tencent_video_role_permission VALUES (15, 3, 41);
INSERT INTO t_tencent_video_role_permission VALUES (16, 3, 45);
INSERT INTO t_tencent_video_role_permission VALUES (17, 3, 49);
INSERT INTO t_tencent_video_role_permission VALUES (18, 3, 53);
INSERT INTO t_tencent_video_role_permission VALUES (19, 3, 57);
INSERT INTO t_tencent_video_role_permission VALUES (20, 3, 61);
-- ----------------------------
-- Records of t_tencent_video_roles
-- ----------------------------
INSERT INTO t_tencent_video_roles VALUES (1, 'free', '大众会员', NULL);
INSERT INTO t_tencent_video_roles VALUES (2, 'qingtong_vip', '青铜会员',1);
INSERT INTO t_tencent_video_roles VALUES (3, 'baiyin_vip','白银会员', 2);
INSERT INTO t_tencent_video_roles VALUES (5, 'general_bobo','普通会员', 1);
INSERT INTO t_tencent_video_roles VALUES (6, 'admin', '网站管理员',NULL);
-- ----------------------------
-- Records of t_tencent_video_user_role
-- ----------------------------
INSERT INTO t_tencent_video_user_role VALUES (1, 1, 5, '2099-12-31 23:59:59');
INSERT INTO t_tencent_video_user_role VALUES (2, 2, 6, '2099-12-31 23:59:59');
-- ----------------------------
-- Records of t_tencent_video_users
-- ----------------------------
INSERT INTO t_tencent_video_users VALUES (1, 'bobo', '$2a$04$lpCeAK7Hv0Wrx2eCg9jS4ubncXYunvDrrAmHOOoMF.7M.pbBNY/lW', '男', '2001-09-16');
INSERT INTO t_tencent_video_users VALUES (2, 'boboadmin', '$2a$04$lpCeAK7Hv0Wrx2eCg9jS4ubncXYunvDrrAmHOOoMF.7M.pbBNY/lW', '男', '2001-09-16');
-- ----------------------------
-- Records of t_tencent_videos
-- ----------------------------
INSERT INTO t_tencent_videos VALUES (1, '86版西游记', 'video_86xiyou');
INSERT INTO t_tencent_videos VALUES (2, '新三国', 'video_new3country');
INSERT INTO t_tencent_videos VALUES (3, '琅琊榜', 'video_langya');
INSERT INTO t_tencent_videos VALUES (4, '黄日华版天龙八部', 'video_huang_dragon');
INSERT INTO t_tencent_videos VALUES (5, '苏有朋版倚天屠龙记', 'video_su_yitian');
INSERT INTO t_tencent_videos VALUES (6, '仙剑奇侠传', 'video_xianjian');
INSERT INTO t_tencent_videos VALUES (7, '仙剑奇侠传三', 'video_xian3');
INSERT INTO t_tencent_videos VALUES (8, '新版水浒传', 'video_shuihu');
INSERT INTO t_tencent_videos VALUES (9, '花千骨', 'video_huaqiangu');
INSERT INTO t_tencent_videos VALUES (10, '宫', 'video_gong');
INSERT INTO t_tencent_videos VALUES (11, '天下第一', 'video_first');
INSERT INTO t_tencent_videos VALUES (12, '胡歌版射雕英雄传', 'video_hu_shediao');
INSERT INTO t_tencent_videos VALUES (13, '轩辕剑之天之痕', 'video_xuanyuan');
INSERT INTO t_tencent_videos VALUES (14, '神话', 'video_shenhua');
INSERT INTO t_tencent_videos VALUES (15, '伪装者', 'video_weizhuang');
INSERT INTO t_tencent_videos VALUES (16, '旋风十一人', 'video_wind11');
INSERT INTO t_tencent_videos VALUES (17, '盗墓笔记', 'video_daomu');
INSERT INTO t_tencent_videos VALUES (18, '爱情公寓', 'video_lovehouse');
INSERT INTO t_tencent_videos VALUES (19, '情深深雨濛濛', 'video_yumeng');
INSERT INTO t_tencent_videos VALUES (20, '旋风少女', 'video_windgirl');
-- ----------------------------
-- Records of t_tencent_video_role_urls
-- ----------------------------
INSERT INTO t_tencent_video_role_urls VALUES (1, 1, '/custom/daily_recommend');
INSERT INTO t_tencent_video_role_urls VALUES (2, 2, '/custom/favorite');
INSERT INTO t_tencent_video_role_urls VALUES (3, 3, '/custom/handpick');

3、redis环境准备

使用单机redis即可,监听localhost:6379。

4、Spring Boot服务准备

项目导入IDEA,运行Spring Boot启动类SpringbootSecurityApp即可启动项目。

通过修改application.yml中的server.port,在单机上运行两个节点,分别监听localhost:8151、localhost:8152。

5、nginx负载均衡准备

# http模块下
http {
upstream webservers{
server localhost:8151;
server localhost:8152;
}
server {
listen 8070;
location / {
proxy_pass http://webservers;
}
}
}

然后启动nginx。

6、nginx静态资源服务器准备

将静态资源文件拷贝到nginx目录下的html/SpringbootSecurity目录下,如下图所示。

Spring Security认证授权练手小项目 腾讯视频VIP权限管理功能_java_03


配置nginx.conf:

# server模块下;root为静态资源存放目录
server {
listen 80;
location / {
root html/SpringbootSecurity;
index index.html index.htm;
}
}

然后启动nginx。

到此为止,所有的部署工作均已完成。浏览器访问 ​​http://localhost/login.html​​ 即可开始使用此系统。

6、项目介绍

1、技术架构

主框架为Spring Boot+Spring Security+Mybatis+Spring Session。

关系型数据库采用Mysql。使用Redis主要存储分布式Session数据。

使用kaptcha生成图形验证码。另外使用了lombok、fastjson、hutool等工具。

通过mybatis-generator自动生成数据库映射文件。

前端主要使用html+jquery框架,请求使用jquery ajax。

2、技术汇总

本文不具体介绍项目中使用的技术,而是我会将项目中Spring Security的一些实现细节再写几篇博客分开讲解,以下是可能要讲解的主题:

  • 会话管理
  • 图形验证码
  • 静态URL权限管理、动态URL权限管理、方法注解权限管理
  • spring security集成spring session实现分布式会话

待博文完成后,我会在这里添加上链接,敬请期待吧。

7、配置数据开发

如何增加一个video?

-- 必要
INSERT INTO t_tencent_videos VALUES ('视频名称', 'video_视频标识符');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:*');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:comment');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:download');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:read');
-- 非必要(与某个vip角色或ROLE_free角色关联)
INSERT INTO t_tencent_video_role_permission VALUES (角色ID, 权限ID);

如何新增一个vip角色?

-- 必要
INSERT INTO t_tencent_video_roles VALUES ('角色标识符_vip', '角色名称',父VIP角色ID);
-- 非必要
-- 给角色绑定用户
INSERT INTO t_tencent_video_user_role VALUES (用户ID, 角色ID, '2099-12-31 23:59:59');
-- 给角色绑定权限
INSERT INTO t_tencent_video_role_permission VALUES (角色ID, 权限ID);
-- 给角色绑定URL(目前动态管理的URL在CustomController中)
INSERT INTO t_tencent_video_role_urls VALUES (角色ID, 'URL');

如何新增一个用户?

-- 必要
INSERT INTO t_tencent_video_users VALUES ('用户名', '$2a$04$lpCeAK7Hv0Wrx2eCg9jS4ubncXYunvDrrAmHOOoMF.7M.pbBNY/lW', '男', '2001-09-16');
INSERT INTO t_tencent_video_roles VALUES ('general_用户名','普通会员', 1);

如何新增一个基于数据库表权限管理的URL?

-- 基于/custom
INSERT INTO t_tencent_video_role_urls VALUES (角色ID, '/custom/类型标识');
-- 在index.html的【更多精彩】中,添加一个按钮
-- <button class="customVideoBtn" custom="类型标识">类型名</button>

-- 不基于/custom
-- 可以随意写controller,然后在index.html写一些按钮监听点击事件去访问这些controller,
-- 然后将这些controller方法对应的url通过数据库表与角色关联起来
-- 但最好不要与WebSecurityConfig静态配置的URL Pattern(/user/**、/admin/**、/app/**)重复


标签:练手,INSERT,Spring,INTO,VIP,video,tencent,VALUES,permissions
From: https://blog.51cto.com/u_14643435/5995509

相关文章