🔖 v1.2.3
This commit is contained in:
commit
f185add546
198 files changed
+11968
No files matched your search
@@ -0,0 +1,22 @@
|
||||
root = true
|
||||
|
||||
# 对所有文件生效
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{java,xml}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.{yml,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# 对后缀名为 md 的文件生效
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
### gradle ###
|
||||
.gradle
|
||||
/build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.settings/
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
bin/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
rebel.xml
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
|
||||
### maven ###
|
||||
target/
|
||||
*.war
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar
|
||||
*.tar.gz
|
||||
|
||||
### logs ####
|
||||
logs
|
||||
|
||||
### temp ignore ###
|
||||
*.log
|
||||
*.cache
|
||||
*.diff
|
||||
*.patch
|
||||
*.tmp
|
||||
*.java~
|
||||
*.properties~
|
||||
*.xml~
|
||||
|
||||
### system ignore ###
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
Servers
|
||||
.metadata
|
||||
upload
|
||||
gen_code
|
||||
@@ -0,0 +1,14 @@
|
||||
Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
Neither the name of the pig4cloud.com developer nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
Author: lengleng (wangiegie@gmail.com)
|
||||
@@ -0,0 +1,51 @@
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/circleci/project/vuejs/vue/dev.svg" alt="Build Status">
|
||||
<img src="https://img.shields.io/badge/Spring%20Cloud-Finchley.RELEASE-blue.svg" alt="Coverage Status">
|
||||
<img src="https://img.shields.io/badge/Spring%20Boot-2.0.3.RELEASE-blue.svg" alt="Downloads">
|
||||
</p>
|
||||
|
||||
<h2 align="center">Supporting Pig Developer Team</h2>
|
||||
|
||||
## 项目官网
|
||||
https://pig4cloud.com
|
||||
|
||||
### 配套代码
|
||||
<a href="https://gitee.wang/pig/pigx-ui" target="_blank">pigx-ui</a>
|
||||
|
||||
### pigx 和 pig 区别
|
||||
|
||||
- 基于最新的Spring Cloud Finchley.RELEASE 版本
|
||||
- 完整的oAuth 流程,资源服务器控制权限
|
||||
- 去除了部分对于开发不友好的中间件
|
||||
|
||||
### 部署说明
|
||||
[部署说明](doc/deploy.md)
|
||||
|
||||
## 协议和授权
|
||||
|
||||
pigX并非一个开源软件,作者保留全部的权利。
|
||||
|
||||
### 🌹权益
|
||||
|
||||
1. 个人使用
|
||||
2. 允许用于学习、毕设等。
|
||||
|
||||
### 🚫禁止
|
||||
|
||||
1. 将本项目的部分或全部代码和资源进行任何形式的再发行(尤其上传GitHub、Gitee )
|
||||
2. 利用本项目的部分或全部代码和资源进行`任何商业行为`
|
||||
3. 举报有奖,抢先体验`pigx 2.0`。
|
||||
|
||||
## 贡献代码
|
||||
|
||||
pigX并非一个开源项目,也不是社区共同创造,其全部功能由作者独立完成。
|
||||
|
||||
如果你愿意放弃所有权利,并将权利无条件转让给pigX作者,欢迎您贡献代码,当然会给予不等金额奖励。
|
||||
|
||||
## 提交反馈
|
||||
|
||||
1. 欢迎提交 issue,请写清楚遇到问题的原因,浏览器和操作系统环境,重现的流程。
|
||||
如果有开发能力,建议在本地调试出出错的代码。
|
||||
|
||||
2. 不接受`功能请求`的 issue,功能请求可能会被直接关闭,请谅解(正确的方式是打赏并附言)。
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
@@ -0,0 +1,58 @@
|
||||
### 写在最前
|
||||
**如果想快速部署pigX,请完全参考本篇文档,如果有个性化的修改(例如:oauth2配置、token 个性化需求),请参考本篇运行起来以后,自行修改。循序渐进**
|
||||
|
||||
### 架构图
|
||||

|
||||
### 一、项目下载
|
||||
|
||||
```
|
||||
git https://www.gitee.wang/pig/pigx.git
|
||||
```
|
||||
|
||||
### 二、配置数据库
|
||||
|
||||
```
|
||||
版本: mysql5.7+
|
||||
|
||||
```
|
||||
基本参数如下:
|
||||

|
||||
|
||||
|
||||
### 三、pig配置修改
|
||||
pigx/pigx-config/src/main/resources/config/application-dev.yml
|
||||
|
||||
```
|
||||
# redis 相关
|
||||
spring:
|
||||
redis:
|
||||
password:
|
||||
host: localhost
|
||||
```
|
||||
pigx/pigx-config/src/main/resources/config/pigx-auth-dev.yml
|
||||
pigx/pigx-config/src/main/resources/config/pigx-upms-dev.yml
|
||||
|
||||
```
|
||||
# 数据源
|
||||
spring:
|
||||
datasource:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: lengleng
|
||||
url: jdbc:mysql://127.0.0.1:3306/pigx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
```
|
||||
|
||||
|
||||
### 四、pigx-ui:
|
||||
|
||||
```
|
||||
git clone https://www.gitee.wang/pig/pigx-ui.git
|
||||
npm run dev
|
||||
```
|
||||
请确保启动顺序
|
||||
1.eureka
|
||||
2.config
|
||||
3.gateway
|
||||
4.auth
|
||||
5.upms
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : 139.224.200.249
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 50721
|
||||
Source Host : 139.224.200.249
|
||||
Source Database : pigx
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 50721
|
||||
File Encoding : utf-8
|
||||
|
||||
Date: 06/26/2018 21:52:22 PM
|
||||
*/
|
||||
|
||||
SET NAMES utf8;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_dept`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_dept`;
|
||||
CREATE TABLE `sys_dept` (
|
||||
`dept_id` int(20) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) DEFAULT NULL COMMENT '部门名称',
|
||||
`order_num` int(11) DEFAULT NULL COMMENT '排序',
|
||||
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) DEFAULT '0' COMMENT '是否删除 -1:已删除 0:正常',
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`dept_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='部门管理';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_dept`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_dept` VALUES ('1', '山东农信', null, '2018-01-22 19:00:23', '2018-01-23 12:40:46', '0', '0'), ('2', '沙县国际', null, '2018-01-22 19:00:38', '2018-01-23 12:42:04', '0', '0'), ('3', '潍坊农信', null, '2018-01-22 19:00:44', '2018-01-23 12:40:56', '0', '1'), ('4', '高新农信', null, '2018-01-22 19:00:52', '2018-01-23 12:41:11', '0', '3'), ('5', '院校农信', null, '2018-01-22 19:00:57', '2018-01-23 12:41:22', '0', '4'), ('6', '潍坊学院农信', '115', '2018-01-22 19:01:06', '2018-03-07 16:22:04', '0', '5'), ('7', '山东沙县', null, '2018-01-22 19:01:57', '2018-01-23 12:42:15', '0', '2'), ('8', '潍坊沙县', null, '2018-01-22 19:02:03', '2018-01-23 12:42:23', '0', '7'), ('9', '高新沙县', null, '2018-01-22 19:02:14', '2018-03-07 16:28:14', '0', '8'), ('10', '测试', '110', '2018-06-26 21:26:59', '2018-06-26 21:27:14', '1', '5');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_dept_relation`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_dept_relation`;
|
||||
CREATE TABLE `sys_dept_relation` (
|
||||
`ancestor` int(11) NOT NULL COMMENT '祖先节点',
|
||||
`descendant` int(11) NOT NULL COMMENT '后代节点',
|
||||
PRIMARY KEY (`ancestor`,`descendant`),
|
||||
KEY `idx1` (`ancestor`),
|
||||
KEY `idx2` (`descendant`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_dept_relation`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_dept_relation` VALUES ('1', '1'), ('1', '3'), ('1', '4'), ('1', '5'), ('1', '6'), ('2', '2'), ('2', '7'), ('2', '8'), ('2', '9'), ('3', '3'), ('3', '4'), ('3', '5'), ('3', '6'), ('4', '4'), ('4', '5'), ('4', '6'), ('5', '5'), ('5', '6'), ('6', '6'), ('7', '7'), ('7', '8'), ('7', '9'), ('8', '8'), ('8', '9'), ('9', '9');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_dict`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_dict`;
|
||||
CREATE TABLE `sys_dict` (
|
||||
`id` int(64) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`value` varchar(100) NOT NULL COMMENT '数据值',
|
||||
`label` varchar(100) NOT NULL COMMENT '标签名',
|
||||
`type` varchar(100) NOT NULL COMMENT '类型',
|
||||
`description` varchar(100) NOT NULL COMMENT '描述',
|
||||
`sort` decimal(10,0) NOT NULL COMMENT '排序(升序)',
|
||||
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`remarks` varchar(255) DEFAULT NULL COMMENT '备注信息',
|
||||
`del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sys_dict_value` (`value`),
|
||||
KEY `sys_dict_label` (`label`),
|
||||
KEY `sys_dict_del_flag` (`del_flag`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='字典表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_dict`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_dict` VALUES ('2', '9', '异常', 'log_type', '日志异常', '1', '2017-12-28 13:06:39', '2018-01-06 10:54:41', null, '0'), ('3', '0', '正常', 'log_type', '正常', '1', '2018-05-11 23:52:57', '2018-05-11 23:52:57', '123', '0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_log`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_log`;
|
||||
CREATE TABLE `sys_log` (
|
||||
`id` bigint(64) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`type` char(1) DEFAULT '1' COMMENT '日志类型',
|
||||
`title` varchar(255) DEFAULT '' COMMENT '日志标题',
|
||||
`service_id` varchar(32) DEFAULT NULL COMMENT '服务ID',
|
||||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`remote_addr` varchar(255) DEFAULT NULL COMMENT '操作IP地址',
|
||||
`user_agent` varchar(1000) DEFAULT NULL COMMENT '用户代理',
|
||||
`request_uri` varchar(255) DEFAULT NULL COMMENT '请求URI',
|
||||
`method` varchar(10) DEFAULT NULL COMMENT '操作方式',
|
||||
`params` text COMMENT '操作提交的数据',
|
||||
`time` mediumtext COMMENT '执行时间',
|
||||
`del_flag` char(1) DEFAULT '0' COMMENT '删除标记',
|
||||
`exception` text COMMENT '异常信息',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sys_log_create_by` (`create_by`),
|
||||
KEY `sys_log_request_uri` (`request_uri`),
|
||||
KEY `sys_log_type` (`type`),
|
||||
KEY `sys_log_create_date` (`create_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='日志表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_menu`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_menu`;
|
||||
CREATE TABLE `sys_menu` (
|
||||
`menu_id` int(11) NOT NULL COMMENT '菜单ID',
|
||||
`name` varchar(32) NOT NULL COMMENT '菜单名称',
|
||||
`permission` varchar(32) DEFAULT NULL COMMENT '菜单权限标识',
|
||||
`path` varchar(128) DEFAULT NULL COMMENT '前端URL',
|
||||
`parent_id` int(11) DEFAULT NULL COMMENT '父菜单ID',
|
||||
`icon` varchar(32) DEFAULT NULL COMMENT '图标',
|
||||
`component` varchar(64) DEFAULT NULL COMMENT 'VUE页面',
|
||||
`sort` int(11) DEFAULT '1' COMMENT '排序值',
|
||||
`type` char(1) DEFAULT NULL COMMENT '菜单类型 (0菜单 1按钮)',
|
||||
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` char(1) DEFAULT '0' COMMENT '0--正常 1--删除',
|
||||
PRIMARY KEY (`menu_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='菜单权限表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_menu`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_menu` VALUES ('1', '系统管理', null, '/admin', '-1', 'icon-xitongguanli', 'Layout', '1', '0', '2017-11-07 20:56:00', '2018-05-14 21:53:22', '0'), ('2', '用户管理', null, 'user', '1', 'icon-yonghuguanli', 'views/admin/user/index', '2', '0', '2017-11-02 22:24:37', '2018-05-14 22:11:35', '0'), ('3', '菜单管理', null, 'menu', '1', 'icon-caidanguanli', 'views/admin/menu/index', '3', '0', '2017-11-08 09:57:27', '2018-05-14 22:11:21', '0'), ('4', '角色管理', null, 'role', '1', 'icon-jiaoseguanli', 'views/admin/role/index', '4', '0', '2017-11-08 10:13:37', '2018-05-14 22:11:19', '0'), ('5', '日志管理', null, 'log', '1', 'icon-rizhiguanli', 'views/admin/log/index', '5', '0', '2017-11-20 14:06:22', '2018-05-14 22:11:18', '0'), ('6', '字典管理', null, 'dict', '1', 'icon-zygl', 'views/admin/dict/index', '6', '0', '2017-11-29 11:30:52', '2018-05-14 22:12:48', '0'), ('7', '部门管理', null, 'dept', '1', 'icon-iconbmgl', 'views/admin/dept/index', '7', '0', '2018-01-20 13:17:19', '2018-05-14 22:11:16', '0'), ('8', '系统监控', null, '', '-1', 'icon-iconbmgl', null, '8', '0', '2018-01-22 12:30:41', '2018-06-24 17:10:11', '1'), ('9', '服务监控', null, 'http://139.224.200.249:5001', '8', 'icon-jiankong', null, '9', '0', '2018-01-23 10:53:33', '2018-06-24 17:10:12', '1'), ('10', 'zipkin监控', null, 'http://139.224.200.249:5002', '8', 'icon-jiankong', null, '11', '0', '2018-01-23 10:55:18', '2018-06-24 17:10:12', '1'), ('11', 'pinpoint监控', null, 'https://pinpoint.pig4cloud.com', '8', 'icon-xiazaihuancun', null, '10', '0', '2018-01-25 11:08:52', '2018-06-24 17:10:12', '1'), ('12', '缓存状态', null, 'http://139.224.200.249:8585', '8', 'icon-ecs-status', null, '12', '0', '2018-01-23 10:56:11', '2018-06-24 17:10:12', '1'), ('13', 'ELK状态', null, 'http://139.224.200.249:5601', '8', 'icon-ecs-status', null, '13', '0', '2018-01-23 10:55:47', '2018-06-24 17:10:12', '1'), ('14', '接口文档', null, 'http://139.224.200.249:9999/swagger-ui.html', '8', 'icon-wendangdocument72', null, '14', '0', '2018-01-23 10:56:43', '2018-06-24 17:10:12', '1'), ('15', '任务监控', null, 'http://139.224.200.249:8899', '8', 'icon-jiankong', null, '15', '0', '2018-01-23 10:55:18', '2018-06-24 17:10:12', '1'), ('22', '用户新增', 'sys_user_add', null, '2', null, null, null, '1', '2017-11-08 09:52:09', '2017-12-04 16:31:10', '0'), ('23', '用户修改', 'sys_user_edit', null, '2', null, null, null, '1', '2017-11-08 09:52:48', '2018-06-26 21:16:57', '0'), ('24', '用户删除', 'sys_user_del', null, '2', null, null, null, '1', '2017-11-08 09:54:01', '2017-12-04 16:31:18', '0'), ('32', '菜单新增', 'sys_menu_add', null, '3', null, null, null, '1', '2017-11-08 10:15:53', '2018-01-20 14:37:50', '0'), ('33', '菜单修改', 'sys_menu_edit', null, '3', null, null, null, '1', '2017-11-08 10:16:23', '2018-01-20 14:37:56', '0'), ('34', '菜单删除', 'sys_menu_del', null, '3', null, null, null, '1', '2017-11-08 10:16:43', '2018-01-20 14:38:03', '0'), ('42', '角色新增', 'sys_role_add', null, '4', null, null, null, '1', '2017-11-08 10:14:18', '2018-04-20 07:21:38', '0'), ('43', '角色修改', 'sys_role_edit', null, '4', null, null, null, '1', '2017-11-08 10:14:41', '2018-04-20 07:21:50', '0'), ('44', '角色删除', 'sys_role_del', null, '4', null, null, null, '1', '2017-11-08 10:14:59', '2018-04-20 07:22:00', '0'), ('45', '分配权限', 'sys_role_perm', null, '4', null, null, null, '1', '2018-04-20 07:22:55', '2018-04-20 07:24:40', '0'), ('52', '日志删除', 'sys_log_del', null, '5', null, null, null, '1', '2017-11-20 20:37:37', '2017-11-28 17:36:52', '0'), ('62', '字典删除', 'sys_dict_del', null, '6', null, null, null, '1', '2017-11-29 11:30:11', '2018-01-07 15:40:51', '0'), ('63', '字典新增', 'sys_dict_add', null, '6', null, null, null, '1', '2018-05-11 22:34:55', null, '0'), ('64', '字典修改', 'sys_dict_edit', null, '6', null, null, null, '1', '2018-05-11 22:36:03', '2018-06-26 21:17:36', '0'), ('72', '部门新增', 'sys_dept_add', null, '7', null, null, null, '1', '2018-01-20 14:56:16', '2018-01-20 21:17:57', '0'), ('73', '部门修改', 'sys_dept_edit', null, '7', null, null, null, '1', '2018-01-20 14:56:59', '2018-01-20 21:17:59', '0'), ('74', '部门删除', 'sys_dept_del', null, '7', null, null, null, '1', '2018-01-20 14:57:28', '2018-01-20 21:18:05', '0'), ('100', '客户端管理', '', 'client', '1', 'icon-bangzhushouji', 'views/admin/client/index', '10', '0', '2018-01-20 13:17:19', '2018-05-15 21:28:10', '0'), ('101', '客户端新增', 'sys_client_add', null, '100', '1', null, null, '1', '2018-05-15 21:35:18', '2018-05-16 10:35:26', '0'), ('102', '客户端修改', 'sys_client_edit', null, '100', null, null, null, '1', '2018-05-15 21:37:06', '2018-06-26 21:17:17', '0'), ('103', '客户端删除', 'sys_client_del', null, '100', null, null, null, '1', '2018-05-15 21:39:16', '2018-05-15 21:52:34', '0'), ('200', '服务监控', null, 'http://127.0.0.1:5001', '1', 'iLine truncated
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_oauth_client_details`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_oauth_client_details`;
|
||||
CREATE TABLE `sys_oauth_client_details` (
|
||||
`client_id` varchar(32) NOT NULL,
|
||||
`resource_ids` varchar(256) DEFAULT NULL,
|
||||
`client_secret` varchar(256) DEFAULT NULL,
|
||||
`scope` varchar(256) DEFAULT NULL,
|
||||
`authorized_grant_types` varchar(256) DEFAULT NULL,
|
||||
`web_server_redirect_uri` varchar(256) DEFAULT NULL,
|
||||
`authorities` varchar(256) DEFAULT NULL,
|
||||
`access_token_validity` int(11) DEFAULT NULL,
|
||||
`refresh_token_validity` int(11) DEFAULT NULL,
|
||||
`additional_information` varchar(4096) DEFAULT NULL,
|
||||
`autoapprove` varchar(256) DEFAULT NULL,
|
||||
PRIMARY KEY (`client_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_oauth_client_details`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_oauth_client_details` VALUES ('app', null, 'app', 'server', 'password,refresh_token', null, null, null, null, null, 'true'), ('pig', null, 'pig', 'server', 'password,refresh_token', null, null, null, null, null, 'false');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_role`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_role`;
|
||||
CREATE TABLE `sys_role` (
|
||||
`role_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`role_name` varchar(64) COLLATE utf8mb4_bin NOT NULL,
|
||||
`role_code` varchar(64) COLLATE utf8mb4_bin NOT NULL,
|
||||
`role_desc` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||
`del_flag` char(1) COLLATE utf8mb4_bin DEFAULT '0' COMMENT '删除标识(0-正常,1-删除)',
|
||||
PRIMARY KEY (`role_id`),
|
||||
UNIQUE KEY `role_idx1_role_code` (`role_code`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_role`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_role` VALUES ('1', 'admin', 'ROLE_ADMIN', '超级管理员', '2017-10-29 15:45:51', '2018-04-22 11:40:29', '0'), ('14', 'demo', 'demo', 'demo用户', '2018-04-20 07:14:32', '2018-06-12 18:43:22', '0'), ('15', 'demo2', 'demo2', 'demo2', '2018-06-12 18:59:38', null, '0'), ('16', 'demo3', 'demo3', 'demo', '2018-06-13 07:07:25', '2018-06-24 17:16:47', '1');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_role_dept`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_role_dept`;
|
||||
CREATE TABLE `sys_role_dept` (
|
||||
`id` int(20) NOT NULL AUTO_INCREMENT,
|
||||
`role_id` int(20) DEFAULT NULL COMMENT '角色ID',
|
||||
`dept_id` int(20) DEFAULT NULL COMMENT '部门ID',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='角色与部门对应关系';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_role_dept`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_role_dept` VALUES ('11', '1', '1'), ('16', '14', '6'), ('17', '15', '5'), ('18', '16', '8');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_role_menu`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_role_menu`;
|
||||
CREATE TABLE `sys_role_menu` (
|
||||
`role_id` int(11) NOT NULL COMMENT '角色ID',
|
||||
`menu_id` int(11) NOT NULL COMMENT '菜单ID',
|
||||
PRIMARY KEY (`role_id`,`menu_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='角色菜单表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_role_menu`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_role_menu` VALUES ('1', '1'), ('1', '2'), ('1', '3'), ('1', '4'), ('1', '5'), ('1', '6'), ('1', '7'), ('1', '22'), ('1', '23'), ('1', '24'), ('1', '32'), ('1', '33'), ('1', '34'), ('1', '42'), ('1', '43'), ('1', '44'), ('1', '45'), ('1', '52'), ('1', '62'), ('1', '63'), ('1', '64'), ('1', '72'), ('1', '73'), ('1', '74'), ('1', '100'), ('1', '101'), ('1', '102'), ('1', '103'), ('1', '200'), ('14', '1'), ('14', '2'), ('14', '3'), ('14', '4'), ('14', '5'), ('14', '6'), ('14', '7'), ('14', '21'), ('14', '22'), ('14', '23'), ('14', '24'), ('14', '31'), ('14', '32'), ('14', '33'), ('14', '34'), ('14', '41'), ('14', '42'), ('14', '43'), ('14', '44'), ('14', '45'), ('14', '51'), ('14', '52'), ('14', '61'), ('14', '62'), ('14', '63'), ('14', '64'), ('14', '71'), ('14', '72'), ('14', '73'), ('14', '74'), ('14', '100'), ('14', '101'), ('14', '102'), ('14', '103'), ('14', '104'), ('14', '110'), ('14', '111'), ('14', '112'), ('14', '113'), ('15', '1'), ('15', '2'), ('15', '3'), ('15', '5'), ('15', '21'), ('15', '22'), ('15', '23'), ('15', '24'), ('15', '31'), ('15', '32'), ('15', '33'), ('15', '34'), ('15', '51'), ('15', '52'), ('16', '1'), ('16', '2'), ('16', '21'), ('16', '22'), ('16', '23'), ('16', '24');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_user`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_user`;
|
||||
CREATE TABLE `sys_user` (
|
||||
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`username` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '用户名',
|
||||
`password` varchar(255) COLLATE utf8mb4_bin NOT NULL,
|
||||
`salt` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '随机盐',
|
||||
`phone` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '简介',
|
||||
`avatar` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '头像',
|
||||
`dept_id` int(11) DEFAULT NULL COMMENT '部门ID',
|
||||
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`del_flag` char(1) COLLATE utf8mb4_bin DEFAULT '0' COMMENT '0-正常,1-删除',
|
||||
PRIMARY KEY (`user_id`),
|
||||
UNIQUE KEY `user_idx1_username` (`username`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC COMMENT='用户表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_user`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_user` VALUES ('1', 'admin', '$2a$10$vg5QNHhCknAqevx9vM2s5esllJEzF/pa8VZXtFYHhhOhUcCw/GWyS', null, '17034642888', null, '1', '2018-04-20 07:15:18', '2018-06-26 11:43:22', '0'), ('4', 'pig', '$2a$10$vg5QNHhCknAqevx9vM2s5esllJEzF/pa8VZXtFYHhhOhUcCw/GWyS', null, '17034642118', null, '1', '2018-04-22 11:39:07', '2018-05-10 18:01:11', '0'), ('5', '0098', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642117', null, '1', '2018-05-29 21:35:03', null, '0'), ('7', '0097', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642001', null, '1', '2018-05-29 21:35:03', null, '0'), ('8', '17034642002', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642002', null, '1', '2018-05-29 21:35:03', null, '0'), ('9', '17034642003', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642003', null, '1', '2018-05-29 21:35:03', null, '0'), ('10', '17034642004', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642004', null, '1', '2018-05-29 21:35:03', null, '0'), ('11', '17034642005', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642005', null, '1', '2018-05-29 21:35:03', null, '0'), ('14', '17034642006', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642006', null, '1', '2018-05-29 21:35:03', null, '0'), ('15', '17034642007', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642007', null, '1', '2018-05-29 21:35:03', null, '0'), ('16', '17034642008', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642008', null, '1', '2018-05-29 21:35:03', null, '0'), ('17', '17034642009', '$2a$10$Rm.6OnUqDoiPGMd60/JzlOPErBeHJzOs39uUanCR.RP7u3uW6s5Mq', null, '17034642009', null, '1', '2018-05-29 21:35:03', null, '0'), ('18', '123456', '$2a$10$P1cRSPAJqfPpKPmQIo/GiuSfrdvRnU0nNWBywqK/lBkrL/K1TOXy6', null, '17034642115', null, '6', '2018-06-12 18:28:42', null, '0'), ('19', 'demo2', '$2a$10$qaNZ/KVvq65.wRo20dDuYOR1Qocuvnj3h9CtrXTimFI3.d1PHJMhi', null, '12345678902', null, '5', '2018-06-12 19:00:02', '2018-06-26 21:36:45', '0'), ('20', 'demo3', '$2a$10$vg5QNHhCknAqevx9vM2s5esllJEzF/pa8VZXtFYHhhOhUcCw/GWyS', null, '11122233344', null, '8', '2018-06-13 07:07:56', '2018-06-13 07:09:00', '0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for `sys_user_role`
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sys_user_role`;
|
||||
CREATE TABLE `sys_user_role` (
|
||||
`user_id` int(11) NOT NULL COMMENT '用户ID',
|
||||
`role_id` int(11) NOT NULL COMMENT '角色ID',
|
||||
PRIMARY KEY (`user_id`,`role_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户角色表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of `sys_user_role`
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `sys_user_role` VALUES ('1', '1'), ('4', '14'), ('5', '1'), ('7', '1'), ('8', '1'), ('9', '1'), ('10', '1'), ('11', '1'), ('12', '1'), ('13', '1'), ('14', '1'), ('15', '1'), ('16', '1'), ('17', '1'), ('18', '14'), ('19', '15');
|
||||
COMMIT;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@@ -0,0 +1,64 @@
|
||||
version: '2'
|
||||
services:
|
||||
pigx-redis:
|
||||
image: redis:4.0.10
|
||||
ports:
|
||||
- 6379:6379
|
||||
restart: always
|
||||
|
||||
pigx-eureka:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./pigx-eureka/Dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- 1025:1025
|
||||
|
||||
pigx-config:
|
||||
links:
|
||||
- pigx-eureka
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./pigx-config/Dockerfile
|
||||
restart: always
|
||||
|
||||
pigx-gateway:
|
||||
links:
|
||||
- pigx-eureka
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./pigx-gateway/Dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- 9999:9999
|
||||
|
||||
pigx-auth:
|
||||
links:
|
||||
- pigx-eureka
|
||||
- pigx-redis
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./pigx-auth/Dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- 3000:3000
|
||||
|
||||
pig-upms:
|
||||
links:
|
||||
- pigx-eureka
|
||||
- pigx-redis
|
||||
- pigx-gateway
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./pigx-upms/pigx-upms-biz/Dockerfile
|
||||
restart: always
|
||||
|
||||
pig-monitor:
|
||||
links:
|
||||
- pigx-eureka
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./pigx-monitor/Dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- 5001:5001
|
||||
@@ -0,0 +1,13 @@
|
||||
FROM anapsix/alpine-java:8_server-jre_unlimited
|
||||
|
||||
MAINTAINER wangiegie@gmail.com
|
||||
|
||||
RUN mkdir -p /pigx/bin/com.pig4cloud/pigx-auth
|
||||
|
||||
WORKDIR /pigx/bin/com.pig4cloud/pigx-auth
|
||||
|
||||
EXPOSE 1025
|
||||
|
||||
ADD ./pigx-auth/target/pigx-auth.jar ./
|
||||
|
||||
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-auth.jar
|
||||
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-auth</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>pigx-auth</name>
|
||||
<description>pigx 认证授权中心,基于 spring security oAuth2</description>
|
||||
|
||||
<dependencies>
|
||||
<!--配置中心客户端-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-config</artifactId>
|
||||
</dependency>
|
||||
<!--upms api、model 模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms-api</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
<!--spring security 、oauth、jwt依赖-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-security</artifactId>
|
||||
<exclusions>
|
||||
<!--旧版本 redis操作有问题-->
|
||||
<exclusion>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
<version>${security.oauth.version}</version>
|
||||
</dependency>
|
||||
<!--数据库-->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<!--排除tomcat依赖-->
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<finalName>${project.name}</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.auth;
|
||||
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月21日
|
||||
* 认证授权中心
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients({"com.pig4cloud.pigx.admin.api.feign"})
|
||||
public class PigxAuthApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PigxAuthApplication.class, args);
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.auth.config;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.security.compoent.PigxWebResponseExceptionTranslator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
|
||||
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/22
|
||||
* 认证服务器配置
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableAuthorizationServer
|
||||
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
|
||||
private final DataSource dataSource;
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
@Override
|
||||
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
|
||||
JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
|
||||
clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT);
|
||||
clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT);
|
||||
clients.withClientDetails(clientDetailsService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
|
||||
oauthServer
|
||||
.allowFormAuthenticationForClients()
|
||||
.checkTokenAccess("permitAll()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
||||
endpoints
|
||||
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
|
||||
.tokenStore(tokenStore())
|
||||
.tokenEnhancer(tokenEnhancer())
|
||||
.authenticationManager(authenticationManager)
|
||||
.reuseRefreshTokens(false)
|
||||
.exceptionTranslator(new PigxWebResponseExceptionTranslator());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Bean
|
||||
public TokenStore tokenStore() {
|
||||
RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
|
||||
tokenStore.setPrefix(SecurityConstants.PIGX_PREFIX + SecurityConstants.OAUTH_PREFIX);
|
||||
return tokenStore;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenEnhancer tokenEnhancer() {
|
||||
return (accessToken, authentication) -> {
|
||||
final Map<String, Object> additionalInfo = new HashMap<>(1);
|
||||
additionalInfo.put("license", SecurityConstants.PIGX_LICENSE);
|
||||
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
|
||||
return accessToken;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.auth.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/22
|
||||
* 认证相关配置
|
||||
*/
|
||||
@Primary
|
||||
@Order(90)
|
||||
@Configuration
|
||||
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/actuator/**", "/oauth/removeToken").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and().csrf().disable();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
|
||||
/**
|
||||
* https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-updated
|
||||
* Encoded password does not look like BCrypt
|
||||
*
|
||||
* @return PasswordEncoder
|
||||
*/
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.auth.endpoint;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/24
|
||||
* 删除token端点
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
public class RevokeTokenEndpoint {
|
||||
private final TokenStore tokenStore;
|
||||
|
||||
/**
|
||||
* 删除token
|
||||
*
|
||||
* @param authHeader Authorization
|
||||
*/
|
||||
@RequestMapping("/oauth/removeToken")
|
||||
public R<Boolean> logout(@RequestHeader(value = "Authorization", required = false) String authHeader) {
|
||||
if (StringUtils.hasText(authHeader)) {
|
||||
String tokenValue = authHeader.replace("Bearer", "").trim();
|
||||
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
|
||||
if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
|
||||
return new R<>(false, "退出失败,token 为空");
|
||||
}
|
||||
tokenStore.removeAccessToken(accessToken);
|
||||
}
|
||||
return new R<>(Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.auth.service;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstant;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户详细信息
|
||||
*
|
||||
* @author lengleng
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class PigxUserDetailsServiceImpl implements UserDetailsService {
|
||||
private final RemoteUserService remoteUserService;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
R<UserInfo> result = remoteUserService.info(username, SecurityConstants.FROM_IN);
|
||||
|
||||
if (result == null || result.getData() == null) {
|
||||
throw new UsernameNotFoundException("用户不存在");
|
||||
}
|
||||
|
||||
UserInfo info = result.getData();
|
||||
Set<String> dbAuthsSet = new HashSet<>();
|
||||
if (ArrayUtil.isNotEmpty(info.getRoles())) {
|
||||
// 获取角色
|
||||
Arrays.stream(info.getRoles()).forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
|
||||
// 获取资源
|
||||
dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
|
||||
|
||||
}
|
||||
Collection<? extends GrantedAuthority> authorities
|
||||
= AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
|
||||
SysUser user = info.getSysUser();
|
||||
boolean enabled = StrUtil.equals(user.getDelFlag(), CommonConstant.STATUS_NORMAL);
|
||||
// 构造security用户
|
||||
return new User(username, SecurityConstants.BCRYPT + user.getPassword(), enabled,
|
||||
true, true, true, authorities);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
server:
|
||||
port: 3000
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: pigx-auth
|
||||
# 配置中心
|
||||
cloud:
|
||||
config:
|
||||
fail-fast: true
|
||||
name: ${spring.application.name}
|
||||
profile: dev
|
||||
discovery:
|
||||
enabled: true
|
||||
service-id: pigx-config
|
||||
|
||||
# 注册中心配置
|
||||
eureka:
|
||||
instance:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
logging:
|
||||
level:
|
||||
root: debug
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.config;
|
||||
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
import com.google.code.kaptcha.util.Config;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2017-12-21 21:12:18
|
||||
*/
|
||||
@Configuration
|
||||
public class KaptchaConfiguration {
|
||||
|
||||
private static final String KAPTCHA_BORDER = "kaptcha.border";
|
||||
private static final String KAPTCHA_TEXTPRODUCER_FONT_COLOR = "kaptcha.textproducer.font.color";
|
||||
private static final String KAPTCHA_TEXTPRODUCER_CHAR_SPACE = "kaptcha.textproducer.char.space";
|
||||
private static final String KAPTCHA_IMAGE_WIDTH = "kaptcha.image.width";
|
||||
private static final String KAPTCHA_IMAGE_HEIGHT = "kaptcha.image.height";
|
||||
private static final String KAPTCHA_TEXTPRODUCER_CHAR_LENGTH = "kaptcha.textproducer.char.length";
|
||||
private static final Object KAPTCHA_IMAGE_FONT_SIZE = "kaptcha.textproducer.font.size";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码宽度
|
||||
*/
|
||||
String DEFAULT_IMAGE_WIDTH = "100";
|
||||
|
||||
/**
|
||||
* 默认生成图像验证码高度
|
||||
*/
|
||||
String DEFAULT_IMAGE_HEIGHT = "40";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码长度
|
||||
*/
|
||||
String DEFAULT_IMAGE_LENGTH = "4";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码过期时间
|
||||
*/
|
||||
int DEFAULT_IMAGE_EXPIRE = 60;
|
||||
/**
|
||||
* 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue.
|
||||
*/
|
||||
String DEFAULT_COLOR_FONT = "black";
|
||||
|
||||
/**
|
||||
* 图片边框
|
||||
*/
|
||||
String DEFAULT_IMAGE_BORDER = "no";
|
||||
/**
|
||||
* 默认图片间隔
|
||||
*/
|
||||
String DEFAULT_CHAR_SPACE = "5";
|
||||
|
||||
/**
|
||||
* 默认保存code的前缀
|
||||
*/
|
||||
String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY";
|
||||
/**
|
||||
* 验证码文字大小
|
||||
*/
|
||||
String DEFAULT_IMAGE_FONT_SIZE = "30";
|
||||
|
||||
@Bean
|
||||
public DefaultKaptcha producer() {
|
||||
Properties properties = new Properties();
|
||||
properties.put(KAPTCHA_BORDER, DEFAULT_IMAGE_BORDER);
|
||||
properties.put(KAPTCHA_TEXTPRODUCER_FONT_COLOR, DEFAULT_COLOR_FONT);
|
||||
properties.put(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, DEFAULT_CHAR_SPACE);
|
||||
properties.put(KAPTCHA_IMAGE_WIDTH, DEFAULT_IMAGE_WIDTH);
|
||||
properties.put(KAPTCHA_IMAGE_HEIGHT, DEFAULT_IMAGE_HEIGHT);
|
||||
properties.put(KAPTCHA_IMAGE_FONT_SIZE, DEFAULT_IMAGE_FONT_SIZE);
|
||||
properties.put(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, DEFAULT_IMAGE_LENGTH);
|
||||
Config config = new Config(properties);
|
||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||
defaultKaptcha.setConfig(config);
|
||||
return defaultKaptcha;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.exception;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
*/
|
||||
public class ValidateCodeException extends Exception {
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.pig4cloud.pigx.gateway.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.gateway.exception.ValidateCodeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/4
|
||||
* 验证码处理
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ImageCodeGatewayFilter extends AbstractGatewayFilterFactory {
|
||||
private static final String OAUTH_TOKEN_URL = "/oauth/token";
|
||||
public static final String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY";
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Object config) {
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
// 不是登录请求,直接向下执行
|
||||
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), OAUTH_TOKEN_URL)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
try {
|
||||
checkCode(request);
|
||||
} catch (ValidateCodeException e) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
response.setStatusCode(HttpStatus.PRECONDITION_REQUIRED);
|
||||
return response.setComplete();
|
||||
}
|
||||
|
||||
return chain.filter(exchange);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查code
|
||||
*
|
||||
* @param request
|
||||
* @throws ValidateCodeException 校验异常
|
||||
*/
|
||||
private void checkCode(ServerHttpRequest request) throws ValidateCodeException {
|
||||
String code = request.getQueryParams().getFirst("code");
|
||||
|
||||
if (StrUtil.isBlank(code)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String randomStr = request.getQueryParams().getFirst("randomStr");
|
||||
if (StrUtil.isBlank(randomStr)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String key = DEFAULT_CODE_KEY + randomStr;
|
||||
if (!redisTemplate.hasKey(key)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
Object codeObj = redisTemplate.opsForValue().get(key);
|
||||
|
||||
if (codeObj == null) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String saveCode = codeObj.toString();
|
||||
if (StrUtil.isBlank(saveCode)) {
|
||||
redisTemplate.delete(key);
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
if (!StrUtil.equals(saveCode, code)) {
|
||||
redisTemplate.delete(key);
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.handle;
|
||||
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import com.pig4cloud.pigx.gateway.filter.ImageCodeGatewayFilter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/5
|
||||
* 验证码生成逻辑处理类
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class ImageCodeHandler implements HandlerFunction<ServerResponse> {
|
||||
private final Producer producer;
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
|
||||
//生成验证码
|
||||
String text = producer.createText();
|
||||
BufferedImage image = producer.createImage(text);
|
||||
|
||||
//保存验证码信息
|
||||
String randomStr = serverRequest.queryParam("randomStr").get();
|
||||
redisTemplate.opsForValue().set(ImageCodeGatewayFilter.DEFAULT_CODE_KEY + randomStr, text, 60, TimeUnit.SECONDS);
|
||||
|
||||
// 转换流信息写出
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||
try {
|
||||
ImageIO.write(image, "jpeg", os);
|
||||
} catch (IOException e) {
|
||||
log.error("ImageIO write err", e);
|
||||
return Mono.error(e);
|
||||
}
|
||||
|
||||
return ServerResponse
|
||||
.status(HttpStatus.OK)
|
||||
.contentType(MediaType.IMAGE_JPEG)
|
||||
.body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray())));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>pigx-common-core</name>
|
||||
<description>pigx 公共工具类核心包</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!--hutool-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<!--fastjson-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
<!--redis-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!--server-api-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${servlet-api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/23
|
||||
* Redis 配置类
|
||||
*/
|
||||
@EnableCaching
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
public class RedisConfig {
|
||||
private final RedisConnectionFactory factory;
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate() {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
|
||||
redisTemplate.setConnectionFactory(factory);
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForHash();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
|
||||
return redisTemplate.opsForValue();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForList();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForSet();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForZSet();
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.constant;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2017/10/29
|
||||
*/
|
||||
public interface CommonConstant {
|
||||
/**
|
||||
* token请求头名称
|
||||
*/
|
||||
String REQ_HEADER = "Authorization";
|
||||
|
||||
/**
|
||||
* token分割符
|
||||
*/
|
||||
String TOKEN_SPLIT = "Bearer ";
|
||||
|
||||
/**
|
||||
* jwt签名
|
||||
*/
|
||||
String SIGN_KEY = "PIG";
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
String STATUS_DEL = "1";
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
String STATUS_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 锁定
|
||||
*/
|
||||
String STATUS_LOCK = "9";
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
String MENU = "0";
|
||||
|
||||
/**
|
||||
* 按钮
|
||||
*/
|
||||
String BUTTON = "1";
|
||||
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
String DEL_FLAG = "del_flag";
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
String UTF8 = "UTF-8";
|
||||
|
||||
/**
|
||||
* JSON 资源
|
||||
*/
|
||||
String CONTENT_TYPE = "application/json; charset=utf-8";
|
||||
|
||||
/**
|
||||
* 阿里大鱼
|
||||
*/
|
||||
String ALIYUN_SMS = "aliyun_sms";
|
||||
|
||||
/**
|
||||
* 路由信息Redis保存的key
|
||||
*/
|
||||
String ROUTE_KEY = "_ROUTE_KEY";
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.constant;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/1/15
|
||||
* MQ 消息队列
|
||||
*/
|
||||
public interface MqQueueConstant {
|
||||
/**
|
||||
* log rabbit队列名称
|
||||
*/
|
||||
String LOG_QUEUE = "log";
|
||||
|
||||
/**
|
||||
* 发送短信验证码队列
|
||||
*/
|
||||
String MOBILE_CODE_QUEUE = "mobile_code_queue";
|
||||
|
||||
/**
|
||||
* 短信服务状态队列
|
||||
*/
|
||||
String MOBILE_SERVICE_STATUS_CHANGE = "mobile_service_status_change";
|
||||
|
||||
/**
|
||||
* 钉钉服务状态队列
|
||||
*/
|
||||
String DINGTALK_SERVICE_STATUS_CHANGE = "dingtalk_service_status_change";
|
||||
|
||||
/**
|
||||
* zipkin 队列
|
||||
*/
|
||||
String ZIPKIN_NAME_QUEUE = "zipkin";
|
||||
|
||||
/**
|
||||
* 路由配置状态队列
|
||||
*/
|
||||
String ROUTE_CONFIG_CHANGE = "route_config_change";
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.constant;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2017-12-18
|
||||
*/
|
||||
public interface SecurityConstants {
|
||||
/**
|
||||
* 角色前缀
|
||||
*/
|
||||
String ROLE = "ROLE_";
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
String PIGX_PREFIX = "pigx_";
|
||||
|
||||
/**
|
||||
* oauth 相关前缀
|
||||
*/
|
||||
String OAUTH_PREFIX = "oauth:";
|
||||
/**
|
||||
* 项目的license
|
||||
*/
|
||||
String PIGX_LICENSE = "made by pigx";
|
||||
|
||||
/**
|
||||
* 内部
|
||||
*/
|
||||
String FROM_IN = "Y";
|
||||
|
||||
/**
|
||||
* {bcrypt} 加密的特征码
|
||||
*/
|
||||
String BCRYPT = "{bcrypt}";
|
||||
/**
|
||||
* sys_oauth_client_details 表的字段,不包括client_id、client_secret
|
||||
*/
|
||||
String CLIENT_FIELDS = "client_id, CONCAT('{noop}',client_secret) as client_secret, resource_ids, scope, "
|
||||
+ "authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, "
|
||||
+ "refresh_token_validity, additional_information, autoapprove";
|
||||
|
||||
/**
|
||||
* JdbcClientDetailsService 查询语句
|
||||
*/
|
||||
String BASE_FIND_STATEMENT = "select " + CLIENT_FIELDS
|
||||
+ " from sys_oauth_client_details";
|
||||
|
||||
/**
|
||||
* 默认的查询语句
|
||||
*/
|
||||
String DEFAULT_FIND_STATEMENT = BASE_FIND_STATEMENT + " order by client_id";
|
||||
|
||||
/**
|
||||
* 按条件client_id 查询
|
||||
*/
|
||||
String DEFAULT_SELECT_STATEMENT = BASE_FIND_STATEMENT + " where client_id = ?";
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.constant;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月22日16:41:01
|
||||
* 服务名称
|
||||
*/
|
||||
public interface ServiceNameConstant {
|
||||
/**
|
||||
* 认证服务的SERVICEID(zuul 配置的对应)
|
||||
*/
|
||||
String AUTH_SERVICE = "pigx-auth";
|
||||
|
||||
/**
|
||||
* UMPS模块
|
||||
*/
|
||||
String UMPS_SERVICE = "pigx-upms";
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.constant.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/1/16
|
||||
* 短信通道枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum EnumSmsChannel {
|
||||
/**
|
||||
* 阿里大鱼短信通道
|
||||
*/
|
||||
ALIYUN("ALIYUN_SMS", "阿里大鱼");
|
||||
/**
|
||||
* 通道名称
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* 通道描述
|
||||
*/
|
||||
private final String description;
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.constant.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author LiXunHuan
|
||||
* @date 2018/1/16
|
||||
* 短信通道模板
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum EnumSmsChannelTemplate {
|
||||
/**
|
||||
* 登录验证
|
||||
*/
|
||||
LOGIN_NAME_LOGIN("loginCodeChannel", "登录验证"),
|
||||
/**
|
||||
* 服务异常提醒
|
||||
*/
|
||||
SERVICE_STATUS_CHANGE("serviceStatusChange", "Pig4Cloud");
|
||||
|
||||
/**
|
||||
* 模板名称
|
||||
*/
|
||||
private final String template;
|
||||
/**
|
||||
* 模板签名
|
||||
*/
|
||||
private final String signName;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.exception;
|
||||
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 😴2018年06月22日16:21:57
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public class CheckedException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CheckedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CheckedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public CheckedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.exception;
|
||||
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月22日16:22:03
|
||||
* 403 授权拒绝
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public class PigDeniedException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public PigDeniedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PigDeniedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public PigDeniedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public PigDeniedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.exception;
|
||||
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月22日16:22:10
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public class UnloginException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UnloginException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UnloginException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public UnloginException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public UnloginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.exception;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月22日16:22:15
|
||||
*/
|
||||
public class ValidateCodeException extends Exception {
|
||||
private static final long serialVersionUID = -7285211528095468156L;
|
||||
|
||||
public ValidateCodeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.util;
|
||||
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.SynthesizingMethodParameter;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 类工具类
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public class ClassUtils extends org.springframework.util.ClassUtils {
|
||||
private static final ParameterNameDiscoverer PARAMETERNAMEDISCOVERER = new DefaultParameterNameDiscoverer();
|
||||
|
||||
/**
|
||||
* 获取方法参数信息
|
||||
*
|
||||
* @param constructor 构造器
|
||||
* @param parameterIndex 参数序号
|
||||
* @return {MethodParameter}
|
||||
*/
|
||||
public static MethodParameter getMethodParameter(Constructor<?> constructor, int parameterIndex) {
|
||||
MethodParameter methodParameter = new SynthesizingMethodParameter(constructor, parameterIndex);
|
||||
methodParameter.initParameterNameDiscovery(PARAMETERNAMEDISCOVERER);
|
||||
return methodParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取方法参数信息
|
||||
*
|
||||
* @param method 方法
|
||||
* @param parameterIndex 参数序号
|
||||
* @return {MethodParameter}
|
||||
*/
|
||||
public static MethodParameter getMethodParameter(Method method, int parameterIndex) {
|
||||
MethodParameter methodParameter = new SynthesizingMethodParameter(method, parameterIndex);
|
||||
methodParameter.initParameterNameDiscovery(PARAMETERNAMEDISCOVERER);
|
||||
return methodParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Annotation
|
||||
*
|
||||
* @param method Method
|
||||
* @param annotationType 注解类
|
||||
* @param <A> 泛型标记
|
||||
* @return {Annotation}
|
||||
*/
|
||||
public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {
|
||||
Class<?> targetClass = method.getDeclaringClass();
|
||||
// The method may be on an interface, but we need attributes from the target class.
|
||||
// If the target class is null, the method will be unchanged.
|
||||
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
|
||||
// If we are dealing with method with generic parameters, find the original method.
|
||||
specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
|
||||
// 先找方法,再找方法上的类
|
||||
A annotation = AnnotatedElementUtils.findMergedAnnotation(specificMethod, annotationType);
|
||||
;
|
||||
if (null != annotation) {
|
||||
return annotation;
|
||||
}
|
||||
// 获取类上面的Annotation,可能包含组合注解,故采用spring的工具类
|
||||
return AnnotatedElementUtils.findMergedAnnotation(specificMethod.getDeclaringClass(), annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Annotation
|
||||
*
|
||||
* @param handlerMethod HandlerMethod
|
||||
* @param annotationType 注解类
|
||||
* @param <A> 泛型标记
|
||||
* @return {Annotation}
|
||||
*/
|
||||
public static <A extends Annotation> A getAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
|
||||
// 先找方法,再找方法上的类
|
||||
A annotation = handlerMethod.getMethodAnnotation(annotationType);
|
||||
if (null != annotation) {
|
||||
return annotation;
|
||||
}
|
||||
// 获取类上面的Annotation,可能包含组合注解,故采用spring的工具类
|
||||
Class<?> beanType = handlerMethod.getBeanType();
|
||||
return AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.util;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 响应信息主体
|
||||
*
|
||||
* @param <T>
|
||||
* @author lengleng
|
||||
*/
|
||||
@ToString
|
||||
public class R<T> implements Serializable {
|
||||
private static final int SUCCESS = 0;
|
||||
private static final int FAIL = 1;
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Getter
|
||||
@Setter
|
||||
private String msg = "success";
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int code = SUCCESS;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private T data;
|
||||
|
||||
public R() {
|
||||
super();
|
||||
}
|
||||
|
||||
public R(T data) {
|
||||
super();
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public R(T data, String msg) {
|
||||
super();
|
||||
this.data = data;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public R(Throwable e) {
|
||||
super();
|
||||
this.msg = e.getMessage();
|
||||
this.code = FAIL;
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/27
|
||||
* Spring 工具类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Lazy(false)
|
||||
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
|
||||
|
||||
private static ApplicationContext applicationContext = null;
|
||||
|
||||
/**
|
||||
* 取得存储在静态变量中的ApplicationContext.
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现ApplicationContextAware接口, 注入Context到静态变量中.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
SpringContextHolder.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getBean(String name) {
|
||||
return (T) applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(Class<T> requiredType) {
|
||||
return applicationContext.getBean(requiredType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除SpringContextHolder中的ApplicationContext为Null.
|
||||
*/
|
||||
public static void clearHolder() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
}
|
||||
applicationContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布事件
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public static void publishEvent(ApplicationEvent event) {
|
||||
if (applicationContext == null) {
|
||||
return;
|
||||
}
|
||||
applicationContext.publishEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现DisposableBean接口, 在Context关闭时清理静态变量.
|
||||
*/
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
SpringContextHolder.clearHolder();
|
||||
}
|
||||
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.core.util;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
|
||||
/**
|
||||
* Miscellaneous utilities for web applications.
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Slf4j
|
||||
public class WebUtils extends org.springframework.web.util.WebUtils {
|
||||
|
||||
public static final String UNKNOWN = "unknown";
|
||||
|
||||
/**
|
||||
* 判断是否ajax请求
|
||||
* spring ajax 返回含有 ResponseBody 或者 RestController注解
|
||||
*
|
||||
* @param handlerMethod HandlerMethod
|
||||
* @return 是否ajax请求
|
||||
*/
|
||||
public static boolean isBody(HandlerMethod handlerMethod) {
|
||||
ResponseBody responseBody = ClassUtils.getAnnotation(handlerMethod, ResponseBody.class);
|
||||
return responseBody != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取cookie
|
||||
*
|
||||
* @param name cookie name
|
||||
* @return cookie value
|
||||
*/
|
||||
public static String getCookieVal(String name) {
|
||||
HttpServletRequest request = WebUtils.getRequest();
|
||||
Assert.notNull(request, "request from RequestContextHolder is null");
|
||||
return getCookieVal(request, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取cookie
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @param name cookie name
|
||||
* @return cookie value
|
||||
*/
|
||||
public static String getCookieVal(HttpServletRequest request, String name) {
|
||||
Cookie cookie = getCookie(request, name);
|
||||
return cookie != null ? cookie.getValue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除 某个指定的cookie
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param key cookie key
|
||||
*/
|
||||
public static void removeCookie(HttpServletResponse response, String key) {
|
||||
setCookie(response, key, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cookie
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param name cookie name
|
||||
* @param value cookie value
|
||||
* @param maxAgeInSeconds maxage
|
||||
*/
|
||||
public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
|
||||
Cookie cookie = new Cookie(name, value);
|
||||
cookie.setPath("/");
|
||||
cookie.setMaxAge(maxAgeInSeconds);
|
||||
cookie.setHttpOnly(true);
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 HttpServletRequest
|
||||
*
|
||||
* @return {HttpServletRequest}
|
||||
*/
|
||||
public static HttpServletRequest getRequest() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 HttpServletResponse
|
||||
*
|
||||
* @return {HttpServletResponse}
|
||||
*/
|
||||
public static HttpServletResponse getResponse() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回json
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param result 结果对象
|
||||
*/
|
||||
public static void renderJson(HttpServletResponse response, Object result) {
|
||||
renderJson(response, result, MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回json
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param result 结果对象
|
||||
* @param contentType contentType
|
||||
*/
|
||||
public static void renderJson(HttpServletResponse response, Object result, String contentType) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType(contentType);
|
||||
try (PrintWriter out = response.getWriter()) {
|
||||
out.append(JSONUtil.toJsonStr(result));
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
public static String getIP() {
|
||||
return getIP(WebUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @return {String}
|
||||
*/
|
||||
public static String getIP(HttpServletRequest request) {
|
||||
Assert.notNull(request, "HttpServletRequest is null");
|
||||
String ip = request.getHeader("X-Requested-For");
|
||||
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Forwarded-For");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return StringUtils.isBlank(ip) ? null : ip.split(",")[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
restart.include.pigx-common-core=/pigx-common-core[\\w-]+\.jar
|
||||
@@ -0,0 +1,3 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.pig4cloud.pigx.common.core.config.RedisConfig,\
|
||||
com.pig4cloud.pigx.common.core.util.SpringContextHolder
|
||||
@@ -0,0 +1 @@
|
||||
provides: hutool-all, spring-cloud-starter-openfeign, feign-okhttp, fastjson, spring-boot-starter-data-redis
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>pigx-common-log</name>
|
||||
<description>pigx 日志服务</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!--工具类核心包-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
<!--UPMS接口模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms-api</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.log;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
|
||||
import com.pig4cloud.pigx.common.log.aspect.SysLogAspect;
|
||||
import com.pig4cloud.pigx.common.log.event.SysLogListener;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/28
|
||||
* 日志自动配置
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@ConditionalOnWebApplication
|
||||
@EnableFeignClients({"com.pig4cloud.pigx.admin.api.feign"})
|
||||
public class LogAutoConfiguration {
|
||||
private final RemoteLogService remoteLogService;
|
||||
|
||||
@Bean
|
||||
public SysLogListener sysLogListener() {
|
||||
return new SysLogListener(remoteLogService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SysLogAspect sysLogAspect() {
|
||||
return new SysLogAspect();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.log.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/28
|
||||
* 操作日志注解
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SysLog {
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.log.aspect;
|
||||
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
import com.pig4cloud.pigx.common.log.event.SysLogEvent;
|
||||
import com.pig4cloud.pigx.common.log.util.SysLogUtils;
|
||||
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
|
||||
/**
|
||||
* 操作日志使用spring event异步入库
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Aspect
|
||||
@Slf4j
|
||||
public class SysLogAspect {
|
||||
|
||||
@Around("@annotation(sysLog)")
|
||||
public Object aroundWxApi(ProceedingJoinPoint point, SysLog sysLog) throws Throwable {
|
||||
String strClassName = point.getTarget().getClass().getName();
|
||||
String strMethodName = point.getSignature().getName();
|
||||
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
|
||||
|
||||
com.pig4cloud.pigx.admin.api.entity.SysLog logVo = SysLogUtils.getSysLog();
|
||||
logVo.setTitle(sysLog.value());
|
||||
// 发送异步日志事件
|
||||
Long startTime = System.currentTimeMillis();
|
||||
Object obj = point.proceed();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
logVo.setTime(endTime - startTime);
|
||||
SpringContextHolder.publishEvent(new SysLogEvent(logVo));
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.log.event;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysLog;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* 系统日志事件
|
||||
*/
|
||||
public class SysLogEvent extends ApplicationEvent {
|
||||
|
||||
public SysLogEvent(SysLog source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.log.event;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysLog;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* 异步监听日志事件
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class SysLogListener {
|
||||
private final RemoteLogService remoteLogService;
|
||||
|
||||
@Async
|
||||
@Order
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveSysLog(SysLogEvent event) {
|
||||
SysLog sysLog = (SysLog) event.getSource();
|
||||
remoteLogService.saveLog(sysLog);
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.log.util;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysLog;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstant;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 系统日志工具类
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public class SysLogUtils {
|
||||
|
||||
private static final String PASSWORD = "password";
|
||||
|
||||
public static SysLog getSysLog() {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
StringBuilder params = new StringBuilder();
|
||||
request.getParameterMap().forEach((key, values) -> {
|
||||
params.append(key).append("=");
|
||||
if (PASSWORD.equalsIgnoreCase(key)) {
|
||||
params.append("******");
|
||||
} else {
|
||||
params.append(ArrayUtil.toString(values));
|
||||
}
|
||||
params.append("&");
|
||||
});
|
||||
|
||||
SysLog sysLog = new SysLog();
|
||||
sysLog.setCreateBy(SecurityUtils.getUser());
|
||||
sysLog.setType(CommonConstant.STATUS_NORMAL);
|
||||
sysLog.setRemoteAddr(HttpUtil.getClientIP(request));
|
||||
sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
|
||||
sysLog.setMethod(request.getMethod());
|
||||
sysLog.setUserAgent(request.getHeader("user-agent"));
|
||||
sysLog.setParams(HttpUtil.toParams(request.getParameterMap()));
|
||||
sysLog.setServiceId(SecurityUtils.getClientId());
|
||||
return sysLog;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
restart.include.pigx-common-security=/pigx-common-log[\\w-]+\.jar
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.pig4cloud.pigx.common.log.LogAutoConfiguration
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>pigx-common-security</name>
|
||||
<description>pigx 安全工具类</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!--工具类核心包-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
<!--安全模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!--feign 依赖-->
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-okhttp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.compoent;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/22
|
||||
* 接口权限判断工具
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("pms")
|
||||
public class PermissionService {
|
||||
/**
|
||||
* 判断接口是否有xxx:xxx权限
|
||||
*
|
||||
* @param permission 权限
|
||||
* @return {boolean}
|
||||
*/
|
||||
public boolean hasPermission(String permission) {
|
||||
if (StrUtil.isBlank(permission)) {
|
||||
return false;
|
||||
}
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (authentication == null) {
|
||||
return false;
|
||||
}
|
||||
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
return authorities.stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.filter(StringUtils::hasText)
|
||||
.anyMatch(x -> PatternMatchUtils.simpleMatch(permission, x));
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.compoent;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/22
|
||||
*/
|
||||
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstant;
|
||||
import com.pig4cloud.pigx.common.core.exception.PigDeniedException;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* 授权拒绝处理器,覆盖默认的OAuth2AccessDeniedHandler
|
||||
* 包装失败信息到PigDeniedException
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class PigAccessDeniedHandler extends OAuth2AccessDeniedHandler {
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 授权拒绝处理,使用R包装
|
||||
*
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @param authException authException
|
||||
* @throws IOException IOException
|
||||
* @throws ServletException ServletException
|
||||
*/
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException authException) throws IOException, ServletException {
|
||||
log.info("授权失败,禁止访问 {}", request.getRequestURI());
|
||||
response.setCharacterEncoding(CommonConstant.UTF8);
|
||||
response.setContentType(CommonConstant.CONTENT_TYPE);
|
||||
R<String> result = new R<>(new PigDeniedException("授权失败,禁止访问"));
|
||||
response.setStatus(HttpStatus.HTTP_FORBIDDEN);
|
||||
PrintWriter printWriter = response.getWriter();
|
||||
printWriter.append(objectMapper.writeValueAsString(result));
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.compoent;
|
||||
|
||||
import com.pig4cloud.pigx.common.security.exception.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.oauth2.common.DefaultThrowableAnalyzer;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.security.web.util.ThrowableAnalyzer;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
* 异常处理,重写oauth 默认实现
|
||||
*/
|
||||
@Slf4j
|
||||
public class PigxWebResponseExceptionTranslator implements WebResponseExceptionTranslator {
|
||||
|
||||
private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();
|
||||
|
||||
@Override
|
||||
public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
|
||||
|
||||
// Try to extract a SpringSecurityException from the stacktrace
|
||||
Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e);
|
||||
|
||||
Exception ase = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class,
|
||||
causeChain);
|
||||
if (ase != null) {
|
||||
return handleOAuth2Exception(new UnauthorizedException(e.getMessage(), e));
|
||||
}
|
||||
|
||||
ase = (AccessDeniedException) throwableAnalyzer
|
||||
.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
|
||||
if (ase != null) {
|
||||
return handleOAuth2Exception(new ForbiddenException(ase.getMessage(), ase));
|
||||
}
|
||||
|
||||
ase = (InvalidGrantException) throwableAnalyzer
|
||||
.getFirstThrowableOfType(InvalidGrantException.class, causeChain);
|
||||
if (ase != null) {
|
||||
return handleOAuth2Exception(new InvalidException(ase.getMessage(), ase));
|
||||
}
|
||||
|
||||
ase = (HttpRequestMethodNotSupportedException) throwableAnalyzer
|
||||
.getFirstThrowableOfType(HttpRequestMethodNotSupportedException.class, causeChain);
|
||||
if (ase != null) {
|
||||
return handleOAuth2Exception(new MethodNotAllowed(ase.getMessage(), ase));
|
||||
}
|
||||
|
||||
ase = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType(
|
||||
OAuth2Exception.class, causeChain);
|
||||
|
||||
if (ase != null) {
|
||||
return handleOAuth2Exception((OAuth2Exception) ase);
|
||||
}
|
||||
|
||||
return handleOAuth2Exception(new ServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), e));
|
||||
|
||||
}
|
||||
|
||||
private ResponseEntity<OAuth2Exception> handleOAuth2Exception(OAuth2Exception e) throws IOException {
|
||||
|
||||
int status = e.getHttpErrorCode();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Cache-Control", "no-store");
|
||||
headers.set("Pragma", "no-cache");
|
||||
if (status == HttpStatus.UNAUTHORIZED.value() || (e instanceof InsufficientScopeException)) {
|
||||
headers.set("WWW-Authenticate", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, e.getSummary()));
|
||||
}
|
||||
|
||||
ResponseEntity<OAuth2Exception> response = new ResponseEntity<>(new PigxAuth2Exception(e.getMessage()), headers,
|
||||
HttpStatus.valueOf(status));
|
||||
|
||||
return response;
|
||||
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.compoent;
|
||||
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstant;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
* 客户端异常处理
|
||||
* 1. 可以根据 AuthenticationException 不同细化异常处理
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class ResourceAuthExceptionEntryPoint implements AuthenticationEntryPoint {
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) throws IOException {
|
||||
response.setCharacterEncoding(CommonConstant.UTF8);
|
||||
response.setContentType(CommonConstant.CONTENT_TYPE);
|
||||
R<String> result = new R<>();
|
||||
result.setCode(HttpStatus.HTTP_UNAUTHORIZED);
|
||||
if (authException != null) {
|
||||
result.setMsg("error");
|
||||
result.setData(authException.getMessage());
|
||||
}
|
||||
response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
|
||||
PrintWriter printWriter = response.getWriter();
|
||||
printWriter.append(objectMapper.writeValueAsString(result));
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
*/
|
||||
public class ForbiddenException extends PigxAuth2Exception {
|
||||
|
||||
public ForbiddenException(String msg, Throwable t) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuth2ErrorCode() {
|
||||
return "access_denied";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpErrorCode() {
|
||||
return HttpStatus.FORBIDDEN.value();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.exception;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
*/
|
||||
public class InvalidException extends PigxAuth2Exception {
|
||||
|
||||
public InvalidException(String msg, Throwable t) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuth2ErrorCode() {
|
||||
return "invalid_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpErrorCode() {
|
||||
return 426;
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
*/
|
||||
public class MethodNotAllowed extends PigxAuth2Exception {
|
||||
|
||||
public MethodNotAllowed(String msg, Throwable t) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuth2ErrorCode() {
|
||||
return "method_not_allowed";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpErrorCode() {
|
||||
return HttpStatus.METHOD_NOT_ALLOWED.value();
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.exception;
|
||||
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
* 自定义OAuth2Exception
|
||||
*/
|
||||
public class PigxAuth2Exception extends OAuth2Exception {
|
||||
|
||||
public PigxAuth2Exception(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
*/
|
||||
public class ServerErrorException extends PigxAuth2Exception {
|
||||
|
||||
public ServerErrorException(String msg, Throwable t) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuth2ErrorCode() {
|
||||
return "server_error";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpErrorCode() {
|
||||
return HttpStatus.INTERNAL_SERVER_ERROR.value();
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/8
|
||||
*/
|
||||
public class UnauthorizedException extends PigxAuth2Exception {
|
||||
|
||||
public UnauthorizedException(String msg, Throwable t) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuth2ErrorCode() {
|
||||
return "unauthorized";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpErrorCode() {
|
||||
return HttpStatus.UNAUTHORIZED.value();
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.interceptor;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.client.OAuth2ClientContext;
|
||||
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/22
|
||||
* feign 拦截器传递 header 中oauth token,
|
||||
* 使用hystrix 的信号量模式
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty("security.oauth2.client.client-id")
|
||||
public class PigxFeignClientIntercept {
|
||||
@Bean
|
||||
public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oAuth2ClientContext,
|
||||
OAuth2ProtectedResourceDetails resource) {
|
||||
return new OAuth2FeignRequestInterceptor(oAuth2ClientContext, resource);
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.util;
|
||||
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 安全工具类
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public class SecurityUtils {
|
||||
|
||||
/**
|
||||
* 获取Authentication
|
||||
*/
|
||||
public static Authentication getAuthentication() {
|
||||
return SecurityContextHolder.getContext().getAuthentication();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户
|
||||
*/
|
||||
public static String getUser(Authentication authentication) {
|
||||
Object principal = authentication.getPrincipal();
|
||||
if (principal == null) {
|
||||
return null;
|
||||
}
|
||||
return (String) principal;
|
||||
}
|
||||
|
||||
public static String getClientId() {
|
||||
Authentication authentication = getAuthentication();
|
||||
if (authentication instanceof OAuth2Authentication) {
|
||||
OAuth2Authentication auth2Authentication = (OAuth2Authentication) authentication;
|
||||
return auth2Authentication.getOAuth2Request().getClientId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户
|
||||
*/
|
||||
public static String getUser() {
|
||||
Authentication authentication = getAuthentication();
|
||||
if (authentication == null) {
|
||||
return null;
|
||||
}
|
||||
return getUser(authentication);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户角色信息
|
||||
*
|
||||
* @return 角色集合
|
||||
*/
|
||||
public static List<String> getRoles() {
|
||||
Authentication authentication = getAuthentication();
|
||||
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
|
||||
List<String> roles = new ArrayList<>();
|
||||
authorities.stream()
|
||||
.filter(granted -> StrUtil.startWith(granted.getAuthority(), SecurityConstants.ROLE))
|
||||
.forEach(granted -> roles.add(StrUtil.removePrefix(granted.getAuthority(), SecurityConstants.ROLE)));
|
||||
return roles;
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
restart.include.pigx-common-security=/pigx-common-security[\\w-]+\.jar
|
||||
@@ -0,0 +1,5 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.pig4cloud.pigx.common.security.compoent.PermissionService,\
|
||||
com.pig4cloud.pigx.common.security.compoent.PigAccessDeniedHandler,\
|
||||
com.pig4cloud.pigx.common.security.compoent.ResourceAuthExceptionEntryPoint,\
|
||||
com.pig4cloud.pigx.common.security.interceptor.PigxFeignClientIntercept
|
||||
@@ -0,0 +1 @@
|
||||
provides: pigx-common-core, spring-cloud-starter-security
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# Neither the name of the pig4cloud.com developer nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
# Author: lengleng (wangiegie@gmail.com)
|
||||
#
|
||||
#
|
||||
AbstractAccessDecisionManager.accessDenied=\u4E0D\u5141\u8BB8\u8BBF\u95EE
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A
|
||||
AbstractSecurityInterceptor.authenticationNotFound=\u672A\u5728SecurityContext\u4E2D\u67E5\u627E\u5230\u8BA4\u8BC1\u5BF9\u8C61
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=\u7528\u6237\u540D\u4E0D\u5B58\u5728\u6216\u8005\u5BC6\u7801\u9519\u8BEF
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=\u7528\u6237\u51ED\u8BC1\u5DF2\u8FC7\u671F
|
||||
AbstractUserDetailsAuthenticationProvider.disabled=\u7528\u6237\u672A\u6FC0\u6D3B
|
||||
AbstractUserDetailsAuthenticationProvider.expired=\u7528\u6237\u5E10\u53F7\u5DF2\u8FC7\u671F
|
||||
AbstractUserDetailsAuthenticationProvider.locked=\u7528\u6237\u5E10\u53F7\u5DF2\u88AB\u9501\u5B9A
|
||||
AbstractUserDetailsAuthenticationProvider.onlySupports=\u4EC5\u4EC5\u652F\u6301UsernamePasswordAuthenticationToken
|
||||
AccountStatusUserDetailsChecker.credentialsExpired=\u7528\u6237\u51ED\u8BC1\u5DF2\u8FC7\u671F
|
||||
AccountStatusUserDetailsChecker.disabled=\u7528\u6237\u672A\u6FC0\u6D3B
|
||||
AccountStatusUserDetailsChecker.expired=\u7528\u6237\u5E10\u53F7\u5DF2\u8FC7\u671F
|
||||
AccountStatusUserDetailsChecker.locked=\u7528\u6237\u5E10\u53F7\u5DF2\u88AB\u9501\u5B9A
|
||||
AclEntryAfterInvocationProvider.noPermission=\u7ED9\u5B9A\u7684Authentication\u5BF9\u8C61({0})\u6839\u672C\u65E0\u6743\u64CD\u63A7\u9886\u57DF\u5BF9\u8C61({1})
|
||||
AnonymousAuthenticationProvider.incorrectKey=\u5C55\u793A\u7684AnonymousAuthenticationToken\u4E0D\u542B\u6709\u9884\u671F\u7684key
|
||||
BindAuthenticator.badCredentials=\u5BC6\u7801\u9519\u8BEF
|
||||
BindAuthenticator.emptyPassword=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A
|
||||
CasAuthenticationProvider.incorrectKey=\u5C55\u793A\u7684CasAuthenticationToken\u4E0D\u542B\u6709\u9884\u671F\u7684key
|
||||
CasAuthenticationProvider.noServiceTicket=\u672A\u80FD\u591F\u6B63\u786E\u63D0\u4F9B\u5F85\u9A8C\u8BC1\u7684CAS\u670D\u52A1\u7968\u6839
|
||||
ConcurrentSessionControlAuthenticationStrategy.exceededAllowed=\u5DF2\u7ECF\u8D85\u8FC7\u4E86\u5F53\u524D\u4E3B\u4F53({0})\u88AB\u5141\u8BB8\u7684\u6700\u5927\u4F1A\u8BDD\u6570\u91CF
|
||||
DigestAuthenticationFilter.incorrectRealm=\u54CD\u5E94\u7ED3\u679C\u4E2D\u7684Realm\u540D\u5B57({0})\u540C\u7CFB\u7EDF\u6307\u5B9A\u7684Realm\u540D\u5B57({1})\u4E0D\u543B\u5408
|
||||
DigestAuthenticationFilter.incorrectResponse=\u9519\u8BEF\u7684\u54CD\u5E94\u7ED3\u679C
|
||||
DigestAuthenticationFilter.missingAuth=\u9057\u6F0F\u4E86\u9488\u5BF9'auth' QOP\u7684\u3001\u5FC5\u987B\u7ED9\u5B9A\u7684\u6458\u8981\u53D6\u503C; \u63A5\u6536\u5230\u7684\u5934\u4FE1\u606F\u4E3A{0}
|
||||
DigestAuthenticationFilter.missingMandatory=\u9057\u6F0F\u4E86\u5FC5\u987B\u7ED9\u5B9A\u7684\u6458\u8981\u53D6\u503C; \u63A5\u6536\u5230\u7684\u5934\u4FE1\u606F\u4E3A{0}
|
||||
DigestAuthenticationFilter.nonceCompromised=Nonce\u4EE4\u724C\u5DF2\u7ECF\u5B58\u5728\u95EE\u9898\u4E86\uFF0C{0}
|
||||
DigestAuthenticationFilter.nonceEncoding=Nonce\u672A\u7ECF\u8FC7Base64\u7F16\u7801; \u76F8\u5E94\u7684nonce\u53D6\u503C\u4E3A {0}
|
||||
DigestAuthenticationFilter.nonceExpired=Nonce\u5DF2\u7ECF\u8FC7\u671F/\u8D85\u65F6
|
||||
DigestAuthenticationFilter.nonceNotNumeric=Nonce\u4EE4\u724C\u7684\u7B2C1\u90E8\u5206\u5E94\u8BE5\u662F\u6570\u5B57\uFF0C\u4F46\u7ED3\u679C\u5374\u662F{0}
|
||||
DigestAuthenticationFilter.nonceNotTwoTokens=Nonce\u5E94\u8BE5\u7531\u4E24\u90E8\u5206\u53D6\u503C\u6784\u6210\uFF0C\u4F46\u7ED3\u679C\u5374\u662F{0}
|
||||
DigestAuthenticationFilter.usernameNotFound=\u7528\u6237\u540D{0}\u672A\u627E\u5230
|
||||
JdbcDaoImpl.noAuthority=\u6CA1\u6709\u4E3A\u7528\u6237{0}\u6307\u5B9A\u89D2\u8272
|
||||
JdbcDaoImpl.notFound=\u672A\u627E\u5230\u7528\u6237{0}
|
||||
LdapAuthenticationProvider.badCredentials=\u574F\u7684\u51ED\u8BC1
|
||||
LdapAuthenticationProvider.credentialsExpired=\u7528\u6237\u51ED\u8BC1\u5DF2\u8FC7\u671F
|
||||
LdapAuthenticationProvider.disabled=\u7528\u6237\u672A\u6FC0\u6D3B
|
||||
LdapAuthenticationProvider.expired=\u7528\u6237\u5E10\u53F7\u5DF2\u8FC7\u671F
|
||||
LdapAuthenticationProvider.locked=\u7528\u6237\u5E10\u53F7\u5DF2\u88AB\u9501\u5B9A
|
||||
LdapAuthenticationProvider.emptyUsername=\u7528\u6237\u540D\u4E0D\u5141\u8BB8\u4E3A\u7A7A
|
||||
LdapAuthenticationProvider.onlySupports=\u4EC5\u4EC5\u652F\u6301UsernamePasswordAuthenticationToken
|
||||
PasswordComparisonAuthenticator.badCredentials=\u574F\u7684\u51ED\u8BC1
|
||||
ProviderManager.providerNotFound=\u672A\u67E5\u627E\u5230\u9488\u5BF9{0}\u7684AuthenticationProvider
|
||||
RememberMeAuthenticationProvider.incorrectKey=\u5C55\u793ARememberMeAuthenticationToken\u4E0D\u542B\u6709\u9884\u671F\u7684key
|
||||
RunAsImplAuthenticationProvider.incorrectKey=\u5C55\u793A\u7684RunAsUserToken\u4E0D\u542B\u6709\u9884\u671F\u7684key
|
||||
SubjectDnX509PrincipalExtractor.noMatching=\u672A\u5728subjectDN\: {0}\u4E2D\u627E\u5230\u5339\u914D\u7684\u6A21\u5F0F
|
||||
SwitchUserFilter.noCurrentUser=\u4E0D\u5B58\u5728\u5F53\u524D\u7528\u6237
|
||||
SwitchUserFilter.noOriginalAuthentication=\u4E0D\u80FD\u591F\u67E5\u627E\u5230\u539F\u5148\u7684\u5DF2\u8BA4\u8BC1\u5BF9\u8C61
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>pigx-common-log</name>
|
||||
<description>pigx 接口文档</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!--安全模块支持swagger security-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
<!--server-api-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${servlet-api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--swagger 依赖-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.swagger.annotation;
|
||||
|
||||
import com.pig4cloud.pigx.common.swagger.config.SwaggerAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/21
|
||||
* 开启pigx swagger
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@Import({SwaggerAutoConfiguration.class})
|
||||
public @interface EnablePigxSwagger2 {
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.swagger.config;
|
||||
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.*;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sywd
|
||||
* swagger配置
|
||||
*/
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
@EnableAutoConfiguration
|
||||
public class SwaggerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public Docket api() {
|
||||
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
|
||||
.apis(RequestHandlerSelectors.any()).paths(PathSelectors.any())
|
||||
.build().securitySchemes(Collections.singletonList(securitySchema()))
|
||||
.securityContexts(Collections.singletonList(securityContext())).pathMapping("/");
|
||||
}
|
||||
|
||||
private SecurityContext securityContext() {
|
||||
return SecurityContext.builder().securityReferences(defaultAuth())
|
||||
.forPaths(PathSelectors.ant("/**"))
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<SecurityReference> defaultAuth() {
|
||||
|
||||
final AuthorizationScope[] authorizationScopes = new AuthorizationScope[3];
|
||||
authorizationScopes[0] = new AuthorizationScope("read", "read all");
|
||||
authorizationScopes[1] = new AuthorizationScope("trust", "trust all");
|
||||
authorizationScopes[2] = new AuthorizationScope("write", "write all");
|
||||
|
||||
return Collections.singletonList(new SecurityReference("pigX OAuth", authorizationScopes));
|
||||
}
|
||||
|
||||
|
||||
private OAuth securitySchema() {
|
||||
ArrayList authorizationScopeList = new ArrayList();
|
||||
authorizationScopeList.add(new AuthorizationScope("server", "server all"));
|
||||
authorizationScopeList.add(new AuthorizationScope("read", "read all"));
|
||||
authorizationScopeList.add(new AuthorizationScope("write", "access all"));
|
||||
|
||||
ArrayList grantTypes = new ArrayList();
|
||||
GrantType creGrant = new ResourceOwnerPasswordCredentialsGrant("http://localhost:9999/auth/oauth/token");
|
||||
|
||||
grantTypes.add(creGrant);
|
||||
return new OAuth("pigX OAuth", authorizationScopeList, grantTypes);
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("PigX Swagger API ")
|
||||
.description("https://gitee.com/log4j/pig/wikis")
|
||||
.termsOfServiceUrl("https://gitee.wang/pig/pigx")
|
||||
.contact(new Contact("冷冷", "https://gitee.wang/pig/pigx", "wangiegie@gmail.com"))
|
||||
.version("2.0")
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>pigx-common</name>
|
||||
<description>pigx 公共聚合模块</description>
|
||||
|
||||
<modules>
|
||||
<module>pigx-common-core</module>
|
||||
<module>pigx-common-log</module>
|
||||
<module>pigx-common-security</module>
|
||||
<module>pigx-common-swagger</module>
|
||||
</modules>
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
FROM anapsix/alpine-java:8_server-jre_unlimited
|
||||
|
||||
MAINTAINER wangiegie@gmail.com
|
||||
|
||||
RUN mkdir -p /pigx/bin/com.pig4cloud/pigx-config
|
||||
|
||||
WORKDIR /pigx/bin/com.pig4cloud/pigx-config
|
||||
|
||||
EXPOSE 1025
|
||||
|
||||
ADD ./pigx-config/target/pigx-config.jar ./
|
||||
|
||||
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-config.jar
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-config</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>pigx-config</name>
|
||||
<description>pigx 配置中心,基于spring cloud config</description>
|
||||
|
||||
<dependencies>
|
||||
<!--配置中心-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-server</artifactId>
|
||||
</dependency>
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<!--排除tomcat依赖-->
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<finalName>${project.name}</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.config;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.config.server.EnableConfigServer;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月22日
|
||||
* 配置中心
|
||||
*/
|
||||
@EnableConfigServer
|
||||
@SpringCloudApplication
|
||||
public class PigxConfigApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PigxConfigApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
server:
|
||||
port: 4001
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: pigx-config
|
||||
profiles:
|
||||
active: native
|
||||
# 配置中心
|
||||
cloud:
|
||||
config:
|
||||
server:
|
||||
native:
|
||||
search-locations: classpath:/config/
|
||||
|
||||
# 注册中心配置
|
||||
eureka:
|
||||
instance:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
|
||||
# 暴露监控端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
@@ -0,0 +1,48 @@
|
||||
# redis 相关
|
||||
spring:
|
||||
redis:
|
||||
password:
|
||||
host: localhost
|
||||
# 暴露监控端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
|
||||
# feign 配置
|
||||
feign:
|
||||
hystrix:
|
||||
enabled: true
|
||||
okhttp:
|
||||
enabled: true
|
||||
httpclient:
|
||||
enabled: false
|
||||
client:
|
||||
config:
|
||||
feignName:
|
||||
connectTimeout: 10000
|
||||
readTimeout: 10000
|
||||
compression:
|
||||
request:
|
||||
enabled: true
|
||||
response:
|
||||
enabled: true
|
||||
# hystrix If you need to use ThreadLocal bound variables in your RequestInterceptor`s
|
||||
# you will need to either set the thread isolation strategy for Hystrix to `SEMAPHORE or disable Hystrix in Feign.
|
||||
hystrix:
|
||||
command:
|
||||
default:
|
||||
execution:
|
||||
isolation:
|
||||
strategy: SEMAPHORE
|
||||
thread:
|
||||
timeoutInMilliseconds: 60000
|
||||
shareSecurityContext: true
|
||||
|
||||
#请求处理的超时时间
|
||||
ribbon:
|
||||
ReadTimeout: 10000
|
||||
ConnectTimeout: 10000
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# 数据源
|
||||
spring:
|
||||
datasource:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: root
|
||||
url: jdbc:mysql://114.116.45.246:13306/pigx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
@@ -0,0 +1,49 @@
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
locator:
|
||||
enabled: true
|
||||
routes:
|
||||
- id: pigx-auth
|
||||
uri: lb://pigx-auth
|
||||
predicates:
|
||||
- Path=/auth/**
|
||||
filters:
|
||||
# 验证码处理
|
||||
- ImageCodeGatewayFilter
|
||||
# 前端密码解密
|
||||
- PasswordDecoderFilter
|
||||
- StripPrefix=1
|
||||
- id: pigx-upms
|
||||
uri: lb://pigx-upms
|
||||
predicates:
|
||||
- Path=/admin/**
|
||||
filters:
|
||||
# Swagger请求头处理
|
||||
- SwaggerHeaderFilter
|
||||
# 请求头清理避免不合法请求头
|
||||
- name: RemoveRequestHeader
|
||||
args:
|
||||
name: from
|
||||
# 限流配置
|
||||
- name: RequestRateLimiter
|
||||
args:
|
||||
key-resolver: '#{@remoteAddrKeyResolver}'
|
||||
redis-rate-limiter.replenishRate: 10
|
||||
redis-rate-limiter.burstCapacity: 20
|
||||
- StripPrefix=1
|
||||
# 降级配置
|
||||
- name: Hystrix
|
||||
args:
|
||||
name: default
|
||||
fallbackUri: 'forward:/fallback'
|
||||
|
||||
security:
|
||||
encode:
|
||||
# 前端密码密钥,必须16位
|
||||
key: 'pigxpigxpigxpigx'
|
||||
|
||||
# 不校验验证码终端
|
||||
ignore:
|
||||
clients:
|
||||
- test
|
||||
@@ -0,0 +1,40 @@
|
||||
## spring security 配置
|
||||
security:
|
||||
oauth2:
|
||||
client:
|
||||
client-id: pig
|
||||
client-secret: pig
|
||||
scope: server
|
||||
resource:
|
||||
token-info-uri: http://localhost:9999/auth/oauth/check_token
|
||||
|
||||
# 数据源
|
||||
spring:
|
||||
datasource:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: root
|
||||
url: jdbc:mysql://114.116.45.246:13306/pigx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
|
||||
#mybaits-plus配置,修改主键类型,mapper.xml、type 别名等
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath:/mapper/*Mapper.xml
|
||||
typeAliasesPackage: com.pig4cloud.pigx.admin.api.entity
|
||||
global-config:
|
||||
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
|
||||
id-type: 0
|
||||
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
|
||||
field-strategy: 1
|
||||
#驼峰下划线转换
|
||||
db-column-underline: true
|
||||
#刷新mapper 调试神器
|
||||
refresh-mapper: true
|
||||
# 逻辑删除字段
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
#自定义SQL注入器
|
||||
sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: true
|
||||
@@ -0,0 +1,13 @@
|
||||
FROM anapsix/alpine-java:8_server-jre_unlimited
|
||||
|
||||
MAINTAINER wangiegie@gmail.com
|
||||
|
||||
RUN mkdir -p /pigx/bin/com.pig4cloud/pigx-eureka
|
||||
|
||||
WORKDIR /pigx/bin/com.pig4cloud/pigx-eureka
|
||||
|
||||
EXPOSE 1025
|
||||
|
||||
ADD ./pigx-eureka/target/pigx-eureka.jar ./
|
||||
|
||||
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-eureka.jar
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.pig4cloud.pigx</groupId>
|
||||
<artifactId>pigx-eureka</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>pigx-eureka</name>
|
||||
<description>pigx 服务中心,基于eureka</description>
|
||||
|
||||
<dependencies>
|
||||
<!--服务中心-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
|
||||
</dependency>
|
||||
<!--security-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<!--排除tomcat依赖-->
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<finalName>${project.name}</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.eureka;
|
||||
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月21日
|
||||
* 服务中心
|
||||
*/
|
||||
@EnableEurekaServer
|
||||
@SpringBootApplication
|
||||
public class PigxEurekaApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PigxEurekaApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.eureka.security;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/12
|
||||
*/
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("actuator/**").permitAll()
|
||||
.anyRequest()
|
||||
.authenticated().and().httpBasic();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
server:
|
||||
port: 1025
|
||||
|
||||
spring:
|
||||
security:
|
||||
user:
|
||||
name: pig
|
||||
password: pig
|
||||
application:
|
||||
name: pigx-eureka
|
||||
|
||||
# docker-compose部署时候 hostname 换成pigx-eureka
|
||||
# 类似的 redis 使用pigx-redis ,gateway 换成 pigx-gateway
|
||||
eureka:
|
||||
instance:
|
||||
hostname: localhost
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
register-with-eureka: false
|
||||
fetch-registry: false
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@${eureka.instance.hostname}:${server.port}/eureka/
|
||||
server:
|
||||
eviction-interval-timer-in-ms: 4000
|
||||
enable-self-preservation: false
|
||||
renewal-percent-threshold: 0.9
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
@@ -0,0 +1,13 @@
|
||||
FROM anapsix/alpine-java:8_server-jre_unlimited
|
||||
|
||||
MAINTAINER wangiegie@gmail.com
|
||||
|
||||
RUN mkdir -p /pigx/bin/com.pig4cloud/pigx-gateway
|
||||
|
||||
WORKDIR /pigx/bin/com.pig4cloud/pigx-gateway
|
||||
|
||||
EXPOSE 1025
|
||||
|
||||
ADD ./pigx-gateway/target/pigx-gateway.jar ./
|
||||
|
||||
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-gateway.jar
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-gateway</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>pigx-gateway</name>
|
||||
<description>pigx 服务网关,基于 spring cloud gateway</description>
|
||||
|
||||
<dependencies>
|
||||
<!--gateway 网关依赖,内置webflux 依赖-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
|
||||
</dependency>
|
||||
<!--配置中心客户端-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-config</artifactId>
|
||||
</dependency>
|
||||
<!--验证码-->
|
||||
<dependency>
|
||||
<groupId>com.github.axet</groupId>
|
||||
<artifactId>kaptcha</artifactId>
|
||||
<version>${kaptcha.version}</version>
|
||||
</dependency>
|
||||
<!--hutool-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<!--接口文档-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<finalName>${project.name}</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway;
|
||||
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年06月21日
|
||||
* 网关应用
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
public class PigxGatewayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PigxGatewayApplication.class, args);
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/22
|
||||
* 网关不简要终端配置
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@RefreshScope
|
||||
@ConditionalOnExpression("!'${ignore}'.isEmpty()")
|
||||
@ConfigurationProperties(prefix = "ignore")
|
||||
public class FilterIgnorePropertiesConfig {
|
||||
private List<String> clients = new ArrayList<>();
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.config;
|
||||
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
import com.google.code.kaptcha.util.Config;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2017-12-21 21:12:18
|
||||
*/
|
||||
@Configuration
|
||||
public class KaptchaConfiguration {
|
||||
|
||||
private static final String KAPTCHA_BORDER = "kaptcha.border";
|
||||
private static final String KAPTCHA_TEXTPRODUCER_FONT_COLOR = "kaptcha.textproducer.font.color";
|
||||
private static final String KAPTCHA_TEXTPRODUCER_CHAR_SPACE = "kaptcha.textproducer.char.space";
|
||||
private static final String KAPTCHA_IMAGE_WIDTH = "kaptcha.image.width";
|
||||
private static final String KAPTCHA_IMAGE_HEIGHT = "kaptcha.image.height";
|
||||
private static final String KAPTCHA_TEXTPRODUCER_CHAR_LENGTH = "kaptcha.textproducer.char.length";
|
||||
private static final Object KAPTCHA_IMAGE_FONT_SIZE = "kaptcha.textproducer.font.size";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码宽度
|
||||
*/
|
||||
private static final String DEFAULT_IMAGE_WIDTH = "100";
|
||||
|
||||
/**
|
||||
* 默认生成图像验证码高度
|
||||
*/
|
||||
private static final String DEFAULT_IMAGE_HEIGHT = "40";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码长度
|
||||
*/
|
||||
private static final String DEFAULT_IMAGE_LENGTH = "4";
|
||||
/**
|
||||
* 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue.
|
||||
*/
|
||||
private static final String DEFAULT_COLOR_FONT = "black";
|
||||
|
||||
/**
|
||||
* 图片边框
|
||||
*/
|
||||
private static final String DEFAULT_IMAGE_BORDER = "no";
|
||||
/**
|
||||
* 默认图片间隔
|
||||
*/
|
||||
private static final String DEFAULT_CHAR_SPACE = "5";
|
||||
/**
|
||||
* 验证码文字大小
|
||||
*/
|
||||
private static final String DEFAULT_IMAGE_FONT_SIZE = "30";
|
||||
|
||||
@Bean
|
||||
public DefaultKaptcha producer() {
|
||||
Properties properties = new Properties();
|
||||
properties.put(KAPTCHA_BORDER, DEFAULT_IMAGE_BORDER);
|
||||
properties.put(KAPTCHA_TEXTPRODUCER_FONT_COLOR, DEFAULT_COLOR_FONT);
|
||||
properties.put(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, DEFAULT_CHAR_SPACE);
|
||||
properties.put(KAPTCHA_IMAGE_WIDTH, DEFAULT_IMAGE_WIDTH);
|
||||
properties.put(KAPTCHA_IMAGE_HEIGHT, DEFAULT_IMAGE_HEIGHT);
|
||||
properties.put(KAPTCHA_IMAGE_FONT_SIZE, DEFAULT_IMAGE_FONT_SIZE);
|
||||
properties.put(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, DEFAULT_IMAGE_LENGTH);
|
||||
Config config = new Config(properties);
|
||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||
defaultKaptcha.setConfig(config);
|
||||
return defaultKaptcha;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.config;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/1
|
||||
* 路由限流配置
|
||||
*/
|
||||
@Configuration
|
||||
public class RateLimiterConfiguration {
|
||||
@Bean(value = "remoteAddrKeyResolver")
|
||||
public KeyResolver remoteAddrKeyResolver() {
|
||||
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.config;
|
||||
|
||||
import com.pig4cloud.pigx.gateway.handle.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/5
|
||||
* 路由配置信息
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
public class RouterFunctionConfiguration {
|
||||
private final HystrixFallbackHandler hystrixFallbackHandler;
|
||||
private final SwaggerResourceHandler swaggerResourceHandler;
|
||||
private final SwaggerSecurityHandler swaggerSecurityHandler;
|
||||
private final SwaggerUiHandler swaggerUiHandler;
|
||||
private final ImageCodeHandler imageCodeHandler;
|
||||
|
||||
@Bean
|
||||
public RouterFunction routerFunction() {
|
||||
return RouterFunctions.route(
|
||||
RequestPredicates.GET("/fallback")
|
||||
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), hystrixFallbackHandler)
|
||||
.andRoute(RequestPredicates.GET("/code")
|
||||
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), imageCodeHandler)
|
||||
.andRoute(RequestPredicates.GET("/swagger-resources")
|
||||
.and(RequestPredicates.accept(MediaType.ALL)), swaggerResourceHandler)
|
||||
.andRoute(RequestPredicates.GET("/swagger-resources/configuration/ui")
|
||||
.and(RequestPredicates.accept(MediaType.ALL)), swaggerUiHandler)
|
||||
.andRoute(RequestPredicates.GET("/swagger-resources/configuration/security")
|
||||
.and(RequestPredicates.accept(MediaType.ALL)), swaggerSecurityHandler);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Component;
|
||||
import springfox.documentation.swagger.web.SwaggerResource;
|
||||
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sywd
|
||||
* 聚合接口文档注册,和zuul实现类似
|
||||
*/
|
||||
@Component
|
||||
@Primary
|
||||
@AllArgsConstructor
|
||||
public class SwaggerProvider implements SwaggerResourcesProvider {
|
||||
public static final String API_URI = "/v2/api-docs";
|
||||
private final RouteLocator routeLocator;
|
||||
private final GatewayProperties gatewayProperties;
|
||||
|
||||
|
||||
@Override
|
||||
public List<SwaggerResource> get() {
|
||||
List<SwaggerResource> resources = new ArrayList<>();
|
||||
List<String> routes = new ArrayList<>();
|
||||
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
|
||||
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
|
||||
.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
|
||||
.filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName()))
|
||||
.filter(predicateDefinition -> !"pigx-auth".equalsIgnoreCase(routeDefinition.getId()))
|
||||
.forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
|
||||
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
|
||||
.replace("/**", API_URI)))));
|
||||
return resources;
|
||||
}
|
||||
|
||||
private SwaggerResource swaggerResource(String name, String location) {
|
||||
SwaggerResource swaggerResource = new SwaggerResource();
|
||||
swaggerResource.setName(name);
|
||||
swaggerResource.setLocation(location);
|
||||
swaggerResource.setSwaggerVersion("2.0");
|
||||
return swaggerResource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.exception;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018年07月22日
|
||||
* 异常包装类
|
||||
*/
|
||||
public class CheckedException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CheckedException() {
|
||||
}
|
||||
|
||||
public CheckedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CheckedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public CheckedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.exception;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
*/
|
||||
public class ValidateCodeException extends Exception {
|
||||
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.filter;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.gateway.config.FilterIgnorePropertiesConfig;
|
||||
import com.pig4cloud.pigx.gateway.exception.CheckedException;
|
||||
import com.pig4cloud.pigx.gateway.exception.ValidateCodeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/4
|
||||
* 验证码处理
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ImageCodeGatewayFilter extends AbstractGatewayFilterFactory {
|
||||
public static final String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY";
|
||||
public static final String OAUTH_TOKEN_URL = "/oauth/token";
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
@Autowired
|
||||
private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Object config) {
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
// 不是登录请求,直接向下执行
|
||||
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), OAUTH_TOKEN_URL)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
// 终端设置不校验, 直接向下执行(1. 从请求参数中获取 2.从header取)
|
||||
String clientId = request.getQueryParams().getFirst("client_id");
|
||||
if (StrUtil.isNotBlank(clientId)) {
|
||||
if (filterIgnorePropertiesConfig.getClients().contains(clientId)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
}
|
||||
try {
|
||||
String[] clientInfos = extractAndDecodeHeader(request);
|
||||
if (filterIgnorePropertiesConfig.getClients().contains(clientInfos[0])) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
response.setStatusCode(HttpStatus.PRECONDITION_REQUIRED);
|
||||
return response.setComplete();
|
||||
}
|
||||
|
||||
//校验验证码合法性
|
||||
try {
|
||||
checkCode(request);
|
||||
} catch (ValidateCodeException e) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
response.setStatusCode(HttpStatus.PRECONDITION_REQUIRED);
|
||||
return response.setComplete();
|
||||
}
|
||||
|
||||
return chain.filter(exchange);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查code
|
||||
*
|
||||
* @param request
|
||||
* @throws ValidateCodeException 校验异常
|
||||
*/
|
||||
private void checkCode(ServerHttpRequest request) throws ValidateCodeException {
|
||||
String code = request.getQueryParams().getFirst("code");
|
||||
|
||||
if (StrUtil.isBlank(code)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String randomStr = request.getQueryParams().getFirst("randomStr");
|
||||
if (StrUtil.isBlank(randomStr)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String key = DEFAULT_CODE_KEY + randomStr;
|
||||
if (!redisTemplate.hasKey(key)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
Object codeObj = redisTemplate.opsForValue().get(key);
|
||||
|
||||
if (codeObj == null) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String saveCode = codeObj.toString();
|
||||
if (StrUtil.isBlank(saveCode)) {
|
||||
redisTemplate.delete(key);
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
if (!StrUtil.equals(saveCode, code)) {
|
||||
redisTemplate.delete(key);
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
private static final String BASIC_ = "Basic ";
|
||||
|
||||
/**
|
||||
* 从header 请求中的clientId/clientsecect
|
||||
*
|
||||
* @param header header中的参数
|
||||
* @throws CheckedException if the Basic header is not present or is not valid
|
||||
* Base64
|
||||
*/
|
||||
public static String[] extractAndDecodeHeader(String header)
|
||||
throws IOException, CheckedException {
|
||||
|
||||
byte[] base64Token = header.substring(6).getBytes("UTF-8");
|
||||
byte[] decoded;
|
||||
try {
|
||||
decoded = Base64.decode(base64Token);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new CheckedException(
|
||||
"Failed to decode basic authentication token");
|
||||
}
|
||||
|
||||
String token = new String(decoded, CharsetUtil.UTF_8);
|
||||
|
||||
int delim = token.indexOf(":");
|
||||
|
||||
if (delim == -1) {
|
||||
throw new CheckedException("Invalid basic authentication token");
|
||||
}
|
||||
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
|
||||
}
|
||||
|
||||
/**
|
||||
* *从header 请求中的clientId/clientsecect
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String[] extractAndDecodeHeader(ServerHttpRequest request)
|
||||
throws IOException, CheckedException {
|
||||
String header = request.getHeaders().getFirst("Authorization");
|
||||
|
||||
if (header == null || !header.startsWith(BASIC_)) {
|
||||
throw new CheckedException("请求头中client信息为空");
|
||||
}
|
||||
|
||||
return extractAndDecodeHeader(header);
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.filter;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/15
|
||||
* 密码解密工具类
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PasswordDecoderFilter extends AbstractGatewayFilterFactory {
|
||||
private static final String PASSWORD = "password";
|
||||
private static final String KEY_ALGORITHM = "AES";
|
||||
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/NOPadding";
|
||||
@Value("${security.encode.key:1234567812345678}")
|
||||
private String encodeKey;
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Object config) {
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
// 不是登录请求,直接向下执行
|
||||
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), ImageCodeGatewayFilter.OAUTH_TOKEN_URL)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
URI uri = exchange.getRequest().getURI();
|
||||
String queryParam = uri.getRawQuery();
|
||||
Map<String, String> paramMap = HttpUtil.decodeParamMap(queryParam, CharsetUtil.UTF_8);
|
||||
|
||||
String password = paramMap.get(PASSWORD);
|
||||
if (StrUtil.isNotBlank(password)) {
|
||||
try {
|
||||
password = decryptAES(password, encodeKey);
|
||||
} catch (Exception e) {
|
||||
log.error("密码解密失败:{}", password);
|
||||
return Mono.error(e);
|
||||
}
|
||||
paramMap.put(PASSWORD, password.trim());
|
||||
}
|
||||
|
||||
URI newUri = UriComponentsBuilder.fromUri(uri)
|
||||
.replaceQuery(HttpUtil.toParams(paramMap))
|
||||
.build(true)
|
||||
.toUri();
|
||||
|
||||
ServerHttpRequest newRequest = exchange.getRequest().mutate().uri(newUri).build();
|
||||
return chain.filter(exchange.mutate().request(newRequest).build());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static String decryptAES(String data, String pass) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
||||
SecretKeySpec keyspec = new SecretKeySpec(pass.getBytes(), KEY_ALGORITHM);
|
||||
IvParameterSpec ivspec = new IvParameterSpec(pass.getBytes());
|
||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||
byte[] result = cipher.doFinal(Base64.decode(data.getBytes(CharsetUtil.UTF_8)));
|
||||
return new String(result, CharsetUtil.UTF_8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.filter;
|
||||
|
||||
import com.pig4cloud.pigx.gateway.config.SwaggerProvider;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Sywd
|
||||
* 添加X-Forwarded-Prefix header
|
||||
*/
|
||||
@Component
|
||||
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
|
||||
private static final String HEADER_NAME = "X-Forwarded-Prefix";
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Object config) {
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
String path = request.getURI().getPath();
|
||||
if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
|
||||
|
||||
|
||||
ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
|
||||
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
|
||||
return chain.filter(newExchange);
|
||||
};
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.handle;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/5
|
||||
* Hystrix 降级处理
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class HystrixFallbackHandler implements HandlerFunction<ServerResponse> {
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
|
||||
log.error("网关执行请求:{}失败,hystrix服务降级处理", serverRequest.uri());
|
||||
return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR.value())
|
||||
.contentType(MediaType.TEXT_PLAIN).body(BodyInserters.fromObject("服务异常"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.handle;
|
||||
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import com.pig4cloud.pigx.gateway.filter.ImageCodeGatewayFilter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/5
|
||||
* 验证码生成逻辑处理类
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class ImageCodeHandler implements HandlerFunction<ServerResponse> {
|
||||
private final Producer producer;
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
|
||||
//生成验证码
|
||||
String text = producer.createText();
|
||||
BufferedImage image = producer.createImage(text);
|
||||
|
||||
//保存验证码信息
|
||||
String randomStr = serverRequest.queryParam("randomStr").get();
|
||||
redisTemplate.opsForValue().set(ImageCodeGatewayFilter.DEFAULT_CODE_KEY + randomStr, text, 60, TimeUnit.SECONDS);
|
||||
|
||||
// 转换流信息写出
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||
try {
|
||||
ImageIO.write(image, "jpeg", os);
|
||||
} catch (IOException e) {
|
||||
log.error("ImageIO write err", e);
|
||||
return Mono.error(e);
|
||||
}
|
||||
|
||||
return ServerResponse
|
||||
.status(HttpStatus.OK)
|
||||
.contentType(MediaType.IMAGE_JPEG)
|
||||
.body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray())));
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.handle;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018-07-19
|
||||
* SwaggerResourceHandler
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class SwaggerResourceHandler implements HandlerFunction<ServerResponse> {
|
||||
private final SwaggerResourcesProvider swaggerResources;
|
||||
|
||||
/**
|
||||
* Handle the given request.
|
||||
*
|
||||
* @param request the request to handle
|
||||
* @return the response
|
||||
*/
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
return ServerResponse.status(HttpStatus.OK)
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.body(BodyInserters.fromObject(swaggerResources.get()));
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.handle;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.SecurityConfiguration;
|
||||
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018-07-19
|
||||
* SwaggerSecurityHandler
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SwaggerSecurityHandler implements HandlerFunction<ServerResponse> {
|
||||
@Autowired(required = false)
|
||||
private SecurityConfiguration securityConfiguration;
|
||||
|
||||
/**
|
||||
* Handle the given request.
|
||||
*
|
||||
* @param request the request to handle
|
||||
* @return the response
|
||||
*/
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
return ServerResponse.status(HttpStatus.OK)
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.body(BodyInserters.fromObject(
|
||||
Optional.ofNullable(securityConfiguration)
|
||||
.orElse(SecurityConfigurationBuilder.builder().build())));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.gateway.handle;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.UiConfiguration;
|
||||
import springfox.documentation.swagger.web.UiConfigurationBuilder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018-07-19
|
||||
* SwaggerUiHandler
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SwaggerUiHandler implements HandlerFunction<ServerResponse> {
|
||||
@Autowired(required = false)
|
||||
private UiConfiguration uiConfiguration;
|
||||
|
||||
/**
|
||||
* Handle the given request.
|
||||
*
|
||||
* @param request the request to handle
|
||||
* @return the response
|
||||
*/
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
return ServerResponse.status(HttpStatus.OK)
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.body(BodyInserters.fromObject(
|
||||
Optional.ofNullable(uiConfiguration)
|
||||
.orElse(UiConfigurationBuilder.builder().build())));
|
||||
}
|
||||
}
|
||||
Loaded 100 of 198 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user