From f111e7f4548b0fac65cf4c2931d3df3d00a62407 Mon Sep 17 00:00:00 2001 From: lbw Date: Fri, 11 Aug 2023 16:06:43 +0800 Subject: [PATCH] =?UTF-8?q?:recycle:=20Refactoring=20code.=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=20sys-log=20=E6=94=AF=E6=8C=81=20body=20=E5=85=A5?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/pig.sql | 13 +- .../pig/common/core/util/RedisUtils.java | 1126 ++++++++--------- pig-common/pig-common-log/pom.xml | 4 + .../pig/common/log/LogAutoConfiguration.java | 13 +- .../pig/common/log/aspect/SysLogAspect.java | 11 +- .../common/log/config/PigLogProperties.java | 54 + .../common/log/event/SysLogEventSource.java | 20 + .../pig/common/log/event/SysLogListener.java | 48 +- .../pig/common/log/util/SysLogUtils.java | 41 +- .../spring-configuration-metadata.json | 30 + .../main/resources/META-INF/spring.factories | 3 - .../PigCustomOpaqueTokenIntrospector.java | 9 +- .../pig/common/security/service/PigUser.java | 7 +- .../spring-configuration-metadata.json | 58 + 14 files changed, 843 insertions(+), 594 deletions(-) create mode 100644 pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/config/PigLogProperties.java create mode 100644 pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogEventSource.java create mode 100644 pig-common/pig-common-log/src/main/resources/META-INF/spring-configuration-metadata.json delete mode 100644 pig-common/pig-common-log/src/main/resources/META-INF/spring.factories create mode 100644 pig-common/pig-common-xss/src/main/resources/META-INF/spring-configuration-metadata.json diff --git a/db/pig.sql b/db/pig.sql index e4de5b5b..cb722f07 100644 --- a/db/pig.sql +++ b/db/pig.sql @@ -246,8 +246,8 @@ CREATE TABLE `sys_log` ( `log_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '日志类型', `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志标题', `service_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '服务ID', - `create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ' ' COMMENT '创建人', - `update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ' ' COMMENT '修改人', + `create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '创建人', + `update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8mb4_general_ci DEFAULT ' ' COMMENT '修改人', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `remote_addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '远程地址', @@ -264,15 +264,6 @@ CREATE TABLE `sys_log` ( KEY `sys_log_create_date` (`create_time`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='日志表'; --- ---------------------------- --- Records of sys_log --- ---------------------------- -BEGIN; -INSERT INTO `sys_log` VALUES (1677218733317345282, '0', '更新角色菜单', NULL, 'anonymousUser', ' ', '2023-07-07 15:31:22', NULL, NULL, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', '/role/menu', 'PUT', '', 46, '0', NULL); -INSERT INTO `sys_log` VALUES (1677218768511750146, '0', '更新角色菜单', NULL, 'anonymousUser', ' ', '2023-07-07 15:31:30', NULL, NULL, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', '/role/menu', 'PUT', '', 59, '0', NULL); -INSERT INTO `sys_log` VALUES (1677218849554092033, '0', '更新角色菜单', NULL, 'anonymousUser', ' ', '2023-07-07 15:31:50', NULL, NULL, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', '/role/menu', 'PUT', '', 45, '0', NULL); -INSERT INTO `sys_log` VALUES (1677218871825846274, '0', '更新角色菜单', NULL, 'anonymousUser', ' ', '2023-07-07 15:31:55', NULL, NULL, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', '/role/menu', 'PUT', '', 9, '0', NULL); -COMMIT; -- ---------------------------- -- Table structure for sys_menu diff --git a/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/util/RedisUtils.java b/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/util/RedisUtils.java index d31d9cd2..c02039a7 100644 --- a/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/util/RedisUtils.java +++ b/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/util/RedisUtils.java @@ -20,620 +20,620 @@ import java.util.concurrent.TimeUnit; @UtilityClass public class RedisUtils { - private static final Long SUCCESS = 1L; + private static final Long SUCCESS = 1L; - /** - * 指定缓存失效时间 - * @param key 键 - * @param time 时间(秒) - */ - public boolean expire(String key, long time) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Optional.ofNullable(redisTemplate) - .filter(template -> time > 0) - .ifPresent(template -> template.expire(key, time, TimeUnit.SECONDS)); - return true; - } + /** + * 指定缓存失效时间 + * @param key 键 + * @param time 时间(秒) + */ + public boolean expire(String key, long time) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Optional.ofNullable(redisTemplate) + .filter(template -> time > 0) + .ifPresent(template -> template.expire(key, time, TimeUnit.SECONDS)); + return true; + } - /** - * 根据 key 获取过期时间 - * @param key 键 不能为null - * @return 时间(秒) 返回0代表为永久有效 - */ - public long getExpire(Object key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return Optional.ofNullable(redisTemplate) - .map(template -> template.getExpire(key, TimeUnit.SECONDS)) - .orElse(-1L); - } + /** + * 根据 key 获取过期时间 + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(Object key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return Optional.ofNullable(redisTemplate) + .map(template -> template.getExpire(key, TimeUnit.SECONDS)) + .orElse(-1L); + } - /** - * 查找匹配key - * @param pattern key - * @return / - */ - public List scan(String pattern) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - ScanOptions options = ScanOptions.scanOptions().match(pattern).build(); - return Optional.ofNullable(redisTemplate).map(template -> { - RedisConnectionFactory factory = template.getConnectionFactory(); - RedisConnection rc = Objects.requireNonNull(factory).getConnection(); - Cursor cursor = rc.scan(options); - List result = new ArrayList<>(); - while (cursor.hasNext()) { - result.add(new String(cursor.next())); - } - RedisConnectionUtils.releaseConnection(rc, factory); - return result; - }).orElse(Collections.emptyList()); - } + /** + * 查找匹配key + * @param pattern key + * @return / + */ + public List scan(String pattern) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + ScanOptions options = ScanOptions.scanOptions().match(pattern).build(); + return Optional.ofNullable(redisTemplate).map(template -> { + RedisConnectionFactory factory = template.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(); + while (cursor.hasNext()) { + result.add(new String(cursor.next())); + } + RedisConnectionUtils.releaseConnection(rc, factory); + return result; + }).orElse(Collections.emptyList()); + } - /** - * 分页查询 key - * @param patternKey key - * @param page 页码 - * @param size 每页数目 - * @return / - */ - public List findKeysForPage(String patternKey, int page, int size) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - ScanOptions options = ScanOptions.scanOptions().match(patternKey).build(); - RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); - RedisConnection rc = Objects.requireNonNull(factory).getConnection(); - Cursor cursor = rc.scan(options); - List result = new ArrayList<>(size); - int tmpIndex = 0; - int fromIndex = page * size; - int toIndex = page * size + size; - while (cursor.hasNext()) { - if (tmpIndex >= fromIndex && tmpIndex < toIndex) { - result.add(new String(cursor.next())); - tmpIndex++; - continue; - } - // 获取到满足条件的数据后,就可以退出了 - if (tmpIndex >= toIndex) { - break; - } - tmpIndex++; - cursor.next(); - } - RedisConnectionUtils.releaseConnection(rc, factory); - return result; - } + /** + * 分页查询 key + * @param patternKey key + * @param page 页码 + * @param size 每页数目 + * @return / + */ + public List findKeysForPage(String patternKey, int page, int size) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + ScanOptions options = ScanOptions.scanOptions().match(patternKey).build(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(size); + int tmpIndex = 0; + int fromIndex = page * size; + int toIndex = page * size + size; + while (cursor.hasNext()) { + if (tmpIndex >= fromIndex && tmpIndex < toIndex) { + result.add(new String(cursor.next())); + tmpIndex++; + continue; + } + // 获取到满足条件的数据后,就可以退出了 + if (tmpIndex >= toIndex) { + break; + } + tmpIndex++; + cursor.next(); + } + RedisConnectionUtils.releaseConnection(rc, factory); + return result; + } - /** - * 判断key是否存在 - * @param key 键 - * @return true 存在 false不存在 - */ - public boolean hasKey(String key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return Optional.ofNullable(redisTemplate).map(template -> template.hasKey(key)).orElse(false); - } + /** + * 判断key是否存在 + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return Optional.ofNullable(redisTemplate).map(template -> template.hasKey(key)).orElse(false); + } - /** - * 删除缓存 - * @param keys 可以传一个值 或多个 - */ - public void del(String... keys) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Optional.ofNullable(keys) - .map(Arrays::asList) - .filter(keysList -> !keysList.isEmpty()) - .ifPresent(redisTemplate::delete); - } + /** + * 删除缓存 + * @param keys 可以传一个值 或多个 + */ + public void del(String... keys) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Optional.ofNullable(keys) + .map(Arrays::asList) + .filter(keysList -> !keysList.isEmpty()) + .ifPresent(redisTemplate::delete); + } - /** - * 获取锁 - * @param lockKey 锁key - * @param value value - * @param expireTime:单位-秒 - * @return boolean - */ - public boolean getLock(String lockKey, String value, int expireTime) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return Optional.ofNullable(redisTemplate) - .map(template -> template.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS)) - .orElse(false); - } + /** + * 获取锁 + * @param lockKey 锁key + * @param value value + * @param expireTime:单位-秒 + * @return boolean + */ + public boolean getLock(String lockKey, String value, int expireTime) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return Optional.ofNullable(redisTemplate) + .map(template -> template.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS)) + .orElse(false); + } - /** - * 释放锁 - * @param lockKey 锁key - * @param value value - * @return boolean - */ - public boolean releaseLock(String lockKey, String value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; - RedisScript redisScript = new DefaultRedisScript<>(script, Long.class); - return Optional.ofNullable(redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value)) - .map(Convert::toLong) - .filter(SUCCESS::equals) - .isPresent(); - } + /** + * 释放锁 + * @param lockKey 锁key + * @param value value + * @return boolean + */ + public boolean releaseLock(String lockKey, String value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; + RedisScript redisScript = new DefaultRedisScript<>(script, Long.class); + return Optional.ofNullable(redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value)) + .map(Convert::toLong) + .filter(SUCCESS::equals) + .isPresent(); + } - // ============================String============================= + // ============================String============================= - /** - * 普通缓存获取 - * @param key 键 - * @return 值 - */ - public T get(String key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForValue().get(key); - } + /** + * 普通缓存获取 + * @param key 键 + * @return 值 + */ + public T get(String key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForValue().get(key); + } - /** - * 批量获取 - * @param keys - * @return - */ - public List multiGet(List keys) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForValue().multiGet(keys); - } + /** + * 批量获取 + * @param keys + * @return + */ + public List multiGet(List keys) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForValue().multiGet(keys); + } - /** - * 普通缓存放入 - * @param key 键 - * @param value 值 - * @return true成功 false失败 - */ - public boolean set(String key, Object value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Optional.ofNullable(redisTemplate).map(template -> { - template.opsForValue().set(key, value); - return true; - }); - return true; - } + /** + * 普通缓存放入 + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Optional.ofNullable(redisTemplate).map(template -> { + template.opsForValue().set(key, value); + return true; + }); + return true; + } - /** - * 普通缓存放入并设置时间 - * @param key 键 - * @param value 值 - * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 - * @return true成功 false 失败 - */ - public boolean set(String key, Object value, long time) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return Optional.ofNullable(redisTemplate).map(template -> { - if (time > 0) { - template.opsForValue().set(key, value, time, TimeUnit.SECONDS); - } - else { - template.opsForValue().set(key, value); - } - return true; - }).orElse(false); - } + /** + * 普通缓存放入并设置时间 + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return Optional.ofNullable(redisTemplate).map(template -> { + if (time > 0) { + template.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } + else { + template.opsForValue().set(key, value); + } + return true; + }).orElse(false); + } - /** - * 普通缓存放入并设置时间 - * @param key 键 - * @param value 值 - * @param time 时间 - * @param timeUnit 类型 - * @return true成功 false 失败 - */ - public boolean set(String key, T value, long time, TimeUnit timeUnit) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Optional.ofNullable(redisTemplate).map(template -> { - if (time > 0) { - template.opsForValue().set(key, value, time, timeUnit); - } - else { - template.opsForValue().set(key, value); - } - return true; - }); - return true; - } + /** + * 普通缓存放入并设置时间 + * @param key 键 + * @param value 值 + * @param time 时间 + * @param timeUnit 类型 + * @return true成功 false 失败 + */ + public boolean set(String key, T value, long time, TimeUnit timeUnit) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Optional.ofNullable(redisTemplate).map(template -> { + if (time > 0) { + template.opsForValue().set(key, value, time, timeUnit); + } + else { + template.opsForValue().set(key, value); + } + return true; + }); + return true; + } - // ================================Map================================= + // ================================Map================================= - /** - * HashGet - * @param key 键 不能为null - * @param hashKey 项 不能为null - * @return 值 - */ - public HV hget(String key, HK hashKey) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForHash().get(key, hashKey); - } + /** + * HashGet + * @param key 键 不能为null + * @param hashKey 项 不能为null + * @return 值 + */ + public HV hget(String key, HK hashKey) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForHash().get(key, hashKey); + } - /** - * 获取hashKey对应的所有键值 - * @param key 键 - * @return 对应的多个键值 - */ - public Map hmget(String key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForHash().entries(key); - } + /** + * 获取hashKey对应的所有键值 + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForHash().entries(key); + } - /** - * HashSet - * @param key 键 - * @param map 对应多个键值 - * @return true 成功 false 失败 - */ - public boolean hmset(String key, Map map) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Optional.ofNullable(redisTemplate).map(template -> { - template.opsForHash().putAll(key, map); - return true; - }); - return true; - } + /** + * HashSet + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Optional.ofNullable(redisTemplate).map(template -> { + template.opsForHash().putAll(key, map); + return true; + }); + return true; + } - /** - * HashSet 并设置时间 - * @param key 键 - * @param map 对应多个键值 - * @param time 时间(秒) - * @return true成功 false失败 - */ - public boolean hmset(String key, Map map, long time) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Optional.ofNullable(redisTemplate).map(template -> { - template.opsForHash().putAll(key, map); - if (time > 0) { - template.expire(key, time, TimeUnit.SECONDS); - } - return true; - }); - return true; - } + /** + * HashSet 并设置时间 + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Optional.ofNullable(redisTemplate).map(template -> { + template.opsForHash().putAll(key, map); + if (time > 0) { + template.expire(key, time, TimeUnit.SECONDS); + } + return true; + }); + return true; + } - /** - * 向一张hash表中放入数据,如果不存在将创建 - * @param key 键 - * @param item 项 - * @param value 值 - * @return true 成功 false失败 - */ - public boolean hset(String key, String item, Object value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return Optional.ofNullable(redisTemplate).map(template -> { - template.opsForHash().put(key, item, value); - return true; - }).orElse(false); - } + /** + * 向一张hash表中放入数据,如果不存在将创建 + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return Optional.ofNullable(redisTemplate).map(template -> { + template.opsForHash().put(key, item, value); + return true; + }).orElse(false); + } - /** - * 向一张hash表中放入数据,如果不存在将创建 - * @param key 键 - * @param item 项 - * @param value 值 - * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 - * @return true 成功 false失败 - */ - public boolean hset(String key, String item, Object value, long time) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return Optional.ofNullable(redisTemplate).map(template -> { - template.opsForHash().put(key, item, value); - if (time > 0) { - template.expire(key, time, TimeUnit.SECONDS); - } - return true; - }).orElse(false); - } + /** + * 向一张hash表中放入数据,如果不存在将创建 + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return Optional.ofNullable(redisTemplate).map(template -> { + template.opsForHash().put(key, item, value); + if (time > 0) { + template.expire(key, time, TimeUnit.SECONDS); + } + return true; + }).orElse(false); + } - /** - * 删除hash表中的值 - * @param key 键 不能为null - * @param item 项 可以使多个 不能为null - */ - public void hdel(String key, Object... item) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - redisTemplate.opsForHash().delete(key, item); - } + /** + * 删除hash表中的值 + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + redisTemplate.opsForHash().delete(key, item); + } - /** - * 判断hash表中是否有该项的值 - * @param key 键 不能为null - * @param item 项 不能为null - * @return true 存在 false不存在 - */ - public boolean hHasKey(String key, String item) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForHash().hasKey(key, item); - } + /** + * 判断hash表中是否有该项的值 + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForHash().hasKey(key, item); + } - /** - * hash递增 如果不存在,就会创建一个 并把新增后的值返回 - * @param key 键 - * @param item 项 - * @param by 要增加几(大于0) - * @return - */ - public double hincr(String key, String item, double by) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForHash().increment(key, item, by); - } + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForHash().increment(key, item, by); + } - /** - * hash递减 - * @param key 键 - * @param item 项 - * @param by 要减少记(小于0) - * @return - */ - public double hdecr(String key, String item, double by) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForHash().increment(key, item, -by); - } + /** + * hash递减 + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForHash().increment(key, item, -by); + } - // ============================set============================= + // ============================set============================= - /** - * 根据key获取Set中的所有值 - * @param key 键 - * @return - */ - public Set sGet(String key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForSet().members(key); - } + /** + * 根据key获取Set中的所有值 + * @param key 键 + * @return + */ + public Set sGet(String key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForSet().members(key); + } - /** - * 根据value从一个set中查询,是否存在 - * @param key 键 - * @param value 值 - * @return true 存在 false不存在 - */ - public boolean sHasKey(String key, Object value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForSet().isMember(key, value); - } + /** + * 根据value从一个set中查询,是否存在 + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForSet().isMember(key, value); + } - /** - * 将数据放入set缓存 - * @param key 键 - * @param values 值 可以是多个 - * @return 成功个数 - */ - public long sSet(String key, Object... values) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForSet().add(key, values); - } + /** + * 将数据放入set缓存 + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForSet().add(key, values); + } - /** - * 将set数据放入缓存 - * @param key 键 - * @param time 时间(秒) - * @param values 值 可以是多个 - * @return 成功个数 - */ - public long sSetAndTime(String key, long time, Object... values) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Long count = redisTemplate.opsForSet().add(key, values); - if (time > 0) { - expire(key, time); - } - return count; - } + /** + * 将set数据放入缓存 + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } - /** - * 获取set缓存的长度 - * @param key 键 - * @return - */ - public long sGetSetSize(String key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForSet().size(key); - } + /** + * 获取set缓存的长度 + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForSet().size(key); + } - /** - * 移除值为value的 - * @param key 键 - * @param values 值 可以是多个 - * @return 移除的个数 - */ - public long setRemove(String key, Object... values) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Long count = redisTemplate.opsForSet().remove(key, values); - return count; - } + /** + * 移除值为value的 + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } - /** - * 获集合key1和集合key2的差集元素 - * @param key 键 - * @return - */ - public Set sDifference(String key, String otherKey) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForSet().difference(key, otherKey); - } + /** + * 获集合key1和集合key2的差集元素 + * @param key 键 + * @return + */ + public Set sDifference(String key, String otherKey) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForSet().difference(key, otherKey); + } - // ===============================list================================= + // ===============================list================================= - /** - * 获取list缓存的内容 - * @param key 键 - * @param start 开始 - * @param end 结束 0 到 -1代表所有值 - * @return - */ - public List lGet(String key, long start, long end) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForList().range(key, start, end); - } + /** + * 获取list缓存的内容 + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForList().range(key, start, end); + } - /** - * 获取list缓存的长度 - * @param key 键 - * @return - */ - public long lGetListSize(String key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForList().size(key); - } + /** + * 获取list缓存的长度 + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForList().size(key); + } - /** - * 通过索引 获取list中的值 - * @param key 键 - * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 - * @return - */ - public Object lGetIndex(String key, long index) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForList().index(key, index); - } + /** + * 通过索引 获取list中的值 + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForList().index(key, index); + } - /** - * 将list放入缓存 - * @param key 键 - * @param value 值 - * @return - */ - public boolean lSet(String key, Object value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - redisTemplate.opsForList().rightPush(key, value); - return true; - } + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + redisTemplate.opsForList().rightPush(key, value); + return true; + } - /** - * 将list放入缓存 - * @param key 键 - * @param value 值 - * @param time 时间(秒) - * @return - */ - public boolean lSet(String key, Object value, long time) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - redisTemplate.opsForList().rightPush(key, value); - if (time > 0) { - Optional.ofNullable(redisTemplate).ifPresent(template -> template.expire(key, time, TimeUnit.SECONDS)); - } - return true; - } + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + Optional.ofNullable(redisTemplate).ifPresent(template -> template.expire(key, time, TimeUnit.SECONDS)); + } + return true; + } - /** - * 将list放入缓存 - * @param key 键 - * @param value 值 - * @return - */ - public boolean lSet(String key, List value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - redisTemplate.opsForList().rightPushAll(key, value); - return true; - } + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } - /** - * 将list放入缓存 - * @param key 键 - * @param value 值 - * @param time 时间(秒) - * @return - */ - public boolean lSet(String key, List value, long time) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - redisTemplate.opsForList().rightPushAll(key, value); - if (time > 0) { - expire(key, time); - } - return true; - } + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } - /** - * 根据索引修改list中的某条数据 - * @param key 键 - * @param index 索引 - * @param value 值 - * @return / - */ - public boolean lUpdateIndex(String key, long index, Object value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - redisTemplate.opsForList().set(key, index, value); - return true; - } + /** + * 根据索引修改list中的某条数据 + * @param key 键 + * @param index 索引 + * @param value 值 + * @return / + */ + public boolean lUpdateIndex(String key, long index, Object value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + redisTemplate.opsForList().set(key, index, value); + return true; + } - /** - * 移除N个值为value - * @param key 键 - * @param count 移除多少个 - * @param value 值 - * @return 移除的个数 - */ - public long lRemove(String key, long count, Object value) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForList().remove(key, count, value); - } + /** + * 移除N个值为value + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForList().remove(key, count, value); + } - /** - * 将zSet数据放入缓存 - * @param key - * @param time - * @param tuples - * @return - */ - public long zSetAndTime(String key, long time, Set> tuples) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - Long count = redisTemplate.opsForZSet().add(key, tuples); - if (time > 0) { - expire(key, time); - } - return count; + /** + * 将zSet数据放入缓存 + * @param key + * @param time + * @param tuples + * @return + */ + public long zSetAndTime(String key, long time, Set> tuples) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + Long count = redisTemplate.opsForZSet().add(key, tuples); + if (time > 0) { + expire(key, time); + } + return count; - } + } - /** - * Sorted set:有序集合获取 - * @param key - * @param min - * @param max - * @return - */ - public Set zRangeByScore(String key, double min, double max) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - ZSetOperations zset = redisTemplate.opsForZSet(); - return zset.rangeByScore(key, min, max); + /** + * Sorted set:有序集合获取 + * @param key + * @param min + * @param max + * @return + */ + public Set zRangeByScore(String key, double min, double max) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + ZSetOperations zset = redisTemplate.opsForZSet(); + return zset.rangeByScore(key, min, max); - } + } - /** - * Sorted set:有序集合获取 正序 - * @param key - * @param start - * @param end - * @return - */ - public Set zRange(String key, long start, long end) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - ZSetOperations zset = redisTemplate.opsForZSet(); - return zset.range(key, start, end); + /** + * Sorted set:有序集合获取 正序 + * @param key + * @param start + * @param end + * @return + */ + public Set zRange(String key, long start, long end) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + ZSetOperations zset = redisTemplate.opsForZSet(); + return zset.range(key, start, end); - } + } - /** - * Sorted set:有序集合获取 倒叙 - * @param key - * @param start - * @param end - * @return - */ - public Set zReverseRange(String key, long start, long end) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - ZSetOperations zset = redisTemplate.opsForZSet(); - return zset.reverseRange(key, start, end); + /** + * Sorted set:有序集合获取 倒叙 + * @param key + * @param start + * @param end + * @return + */ + public Set zReverseRange(String key, long start, long end) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + ZSetOperations zset = redisTemplate.opsForZSet(); + return zset.reverseRange(key, start, end); - } + } - /** - * 获取zSet缓存的长度 - * @param key 键 - * @return - */ - public long zGetSetSize(String key) { - RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); - return redisTemplate.opsForZSet().size(key); - } + /** + * 获取zSet缓存的长度 + * @param key 键 + * @return + */ + public long zGetSetSize(String key) { + RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); + return redisTemplate.opsForZSet().size(key); + } } diff --git a/pig-common/pig-common-log/pom.xml b/pig-common/pig-common-log/pom.xml index 2cb020c5..5f01c23f 100755 --- a/pig-common/pig-common-log/pom.xml +++ b/pig-common/pig-common-log/pom.xml @@ -54,5 +54,9 @@ org.springframework.security spring-security-core + + org.springframework.security + spring-security-oauth2-core + diff --git a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/LogAutoConfiguration.java b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/LogAutoConfiguration.java index ef0d1622..1f3b46ff 100755 --- a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/LogAutoConfiguration.java +++ b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/LogAutoConfiguration.java @@ -18,9 +18,10 @@ package com.pig4cloud.pig.common.log; import com.pig4cloud.pig.admin.api.feign.RemoteLogService; import com.pig4cloud.pig.common.log.aspect.SysLogAspect; +import com.pig4cloud.pig.common.log.config.PigLogProperties; import com.pig4cloud.pig.common.log.event.SysLogListener; -import lombok.RequiredArgsConstructor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; @@ -30,14 +31,14 @@ import org.springframework.scheduling.annotation.EnableAsync; * @date 2019/2/1 日志自动配置 */ @EnableAsync -@RequiredArgsConstructor -@ConditionalOnWebApplication @Configuration(proxyBeanMethods = false) +@EnableConfigurationProperties(PigLogProperties.class) +@ConditionalOnProperty(value = "security.log.enabled", matchIfMissing = true) public class LogAutoConfiguration { @Bean - public SysLogListener sysLogListener(RemoteLogService remoteLogService) { - return new SysLogListener(remoteLogService); + public SysLogListener sysLogListener(PigLogProperties logProperties, RemoteLogService remoteLogService) { + return new SysLogListener(remoteLogService, logProperties); } @Bean diff --git a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/aspect/SysLogAspect.java b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/aspect/SysLogAspect.java index 87569f09..59619c74 100755 --- a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/aspect/SysLogAspect.java +++ b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/aspect/SysLogAspect.java @@ -17,11 +17,12 @@ package com.pig4cloud.pig.common.log.aspect; import cn.hutool.core.util.StrUtil; -import com.pig4cloud.pig.admin.api.entity.SysLog; import com.pig4cloud.pig.common.core.util.SpringContextHolder; import com.pig4cloud.pig.common.log.event.SysLogEvent; +import com.pig4cloud.pig.common.log.event.SysLogEventSource; import com.pig4cloud.pig.common.log.util.LogTypeEnum; import com.pig4cloud.pig.common.log.util.SysLogUtils; +import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; @@ -37,6 +38,7 @@ import org.springframework.expression.EvaluationContext; */ @Aspect @Slf4j +@RequiredArgsConstructor public class SysLogAspect { @Around("@annotation(sysLog)") @@ -62,9 +64,12 @@ public class SysLogAspect { } } - SysLog logVo = SysLogUtils.getSysLog(); + SysLogEventSource logVo = SysLogUtils.getSysLog(); logVo.setTitle(value); - + // 获取请求body参数 + if (StrUtil.isBlank(logVo.getParams())) { + logVo.setBody(point.getArgs()); + } // 发送异步日志事件 Long startTime = System.currentTimeMillis(); Object obj; diff --git a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/config/PigLogProperties.java b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/config/PigLogProperties.java new file mode 100644 index 00000000..5891ada1 --- /dev/null +++ b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/config/PigLogProperties.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.pig4cloud.pig.common.log.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.List; + +/** + * 日志配置类 + * + * @author L.cm + */ +@Getter +@Setter +@ConfigurationProperties(PigLogProperties.PREFIX) +public class PigLogProperties { + + public static final String PREFIX = "security.log"; + + /** + * 开启日志记录 + */ + private boolean enabled = true; + + /** + * 放行字段,password,mobile,idcard,phone + */ + @Value("${security.log.exclude-fields:password,mobile,idcard,phone}") + private List excludeFields; + + /** + * 请求报文最大存储长度 + */ + private Integer maxLength = 2000; + +} diff --git a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogEventSource.java b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogEventSource.java new file mode 100644 index 00000000..a1bf7da7 --- /dev/null +++ b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogEventSource.java @@ -0,0 +1,20 @@ +package com.pig4cloud.pig.common.log.event; + +import com.pig4cloud.pig.admin.api.entity.SysLog; +import lombok.Data; + +/** + * spring event log + * + * @author lengleng + * @date 2023/8/11 + */ +@Data +public class SysLogEventSource extends SysLog { + + /** + * 参数重写成object + */ + private Object body; + +} diff --git a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogListener.java b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogListener.java index cd217423..581db9c5 100755 --- a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogListener.java +++ b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/event/SysLogListener.java @@ -16,30 +16,74 @@ package com.pig4cloud.pig.common.log.event; +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.annotation.JsonFilter; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ser.FilterProvider; +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; import com.pig4cloud.pig.admin.api.entity.SysLog; import com.pig4cloud.pig.admin.api.feign.RemoteLogService; import com.pig4cloud.pig.common.core.constant.SecurityConstants; +import com.pig4cloud.pig.common.core.jackson.PigJavaTimeModule; +import com.pig4cloud.pig.common.log.config.PigLogProperties; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.InitializingBean; import org.springframework.context.event.EventListener; import org.springframework.core.annotation.Order; import org.springframework.scheduling.annotation.Async; +import java.util.Objects; + /** * @author lengleng 异步监听日志事件 */ @Slf4j @RequiredArgsConstructor -public class SysLogListener { +public class SysLogListener implements InitializingBean { + + // new 一个 避免日志脱敏策略影响全局ObjectMapper + private final static ObjectMapper objectMapper = new ObjectMapper(); private final RemoteLogService remoteLogService; + private final PigLogProperties logProperties; + + @SneakyThrows @Async @Order @EventListener(SysLogEvent.class) public void saveSysLog(SysLogEvent event) { - SysLog sysLog = (SysLog) event.getSource(); + SysLogEventSource source = (SysLogEventSource) event.getSource(); + SysLog sysLog = new SysLog(); + BeanUtils.copyProperties(source, sysLog); + + // json 格式刷参数放在异步中处理,提升性能 + if (Objects.nonNull(source.getBody())) { + String params = objectMapper.writeValueAsString(source.getBody()); + sysLog.setParams(StrUtil.subPre(params, logProperties.getMaxLength())); + } + remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN); } + @Override + public void afterPropertiesSet() { + objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class); + String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]); + + FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name", + SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)); + objectMapper.setFilterProvider(filters); + objectMapper.registerModule(new PigJavaTimeModule()); + } + + @JsonFilter("filter properties by name") + class PropertyFilterMixIn { + + } + } diff --git a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java index 53c0cc65..e431db28 100755 --- a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java +++ b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java @@ -16,9 +16,15 @@ package com.pig4cloud.pig.common.log.util; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.URLUtil; +import cn.hutool.extra.servlet.JakartaServletUtil; import cn.hutool.http.HttpUtil; -import com.pig4cloud.pig.admin.api.entity.SysLog; +import com.pig4cloud.pig.common.core.constant.SecurityConstants; +import com.pig4cloud.pig.common.core.util.SpringContextHolder; +import com.pig4cloud.pig.common.log.config.PigLogProperties; +import com.pig4cloud.pig.common.log.event.SysLogEventSource; import jakarta.servlet.http.HttpServletRequest; import lombok.experimental.UtilityClass; import org.springframework.core.StandardReflectionParameterNameDiscoverer; @@ -29,10 +35,12 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.http.HttpHeaders; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import java.lang.reflect.Method; +import java.util.Map; import java.util.Objects; /** @@ -43,16 +51,23 @@ import java.util.Objects; @UtilityClass public class SysLogUtils { - public SysLog getSysLog() { + public SysLogEventSource getSysLog() { HttpServletRequest request = ((ServletRequestAttributes) Objects .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); - SysLog sysLog = new SysLog(); + SysLogEventSource sysLog = new SysLogEventSource(); sysLog.setLogType(LogTypeEnum.NORMAL.getType()); sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI())); sysLog.setMethod(request.getMethod()); + sysLog.setRemoteAddr(JakartaServletUtil.getClientIP(request)); sysLog.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); - sysLog.setParams(HttpUtil.toParams(request.getParameterMap())); sysLog.setCreateBy(getUsername()); + sysLog.setServiceId(getClientId()); + + // get 参数脱敏 + PigLogProperties logProperties = SpringContextHolder.getBean(PigLogProperties.class); + Map paramsMap = MapUtil.removeAny(request.getParameterMap(), + ArrayUtil.toArray(logProperties.getExcludeFields(), String.class)); + sysLog.setParams(HttpUtil.toParams(paramsMap)); return sysLog; } @@ -100,4 +115,22 @@ public class SysLogUtils { return context; } + /** + * 获取客户端 + * @return clientId + */ + private String getClientId() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return null; + } + + Object principal = authentication.getPrincipal(); + if (principal instanceof OAuth2AuthenticatedPrincipal) { + OAuth2AuthenticatedPrincipal auth2Authentication = (OAuth2AuthenticatedPrincipal) principal; + return MapUtil.getStr(auth2Authentication.getAttributes(), SecurityConstants.CLIENT_ID); + } + return null; + } + } diff --git a/pig-common/pig-common-log/src/main/resources/META-INF/spring-configuration-metadata.json b/pig-common/pig-common-log/src/main/resources/META-INF/spring-configuration-metadata.json new file mode 100644 index 00000000..951a9beb --- /dev/null +++ b/pig-common/pig-common-log/src/main/resources/META-INF/spring-configuration-metadata.json @@ -0,0 +1,30 @@ +{ + "groups": [ + { + "name": "security.log", + "type": "com.pig4cloud.pig.common.log.config.PigLogProperties", + "sourceType": "com.pig4cloud.pig.common.log.config.PigLogProperties" + } + ], + "properties": [ + { + "name": "security.log.enabled", + "type": "java.lang.Boolean", + "description": "开启日志记录", + "sourceType": "com.pig4cloud.pig.common.log.config.PigLogProperties" + }, + { + "name": "security.log.exclude-fields", + "type": "java.util.List", + "description": "放行字段,password,mobile,idcard,phone", + "sourceType": "com.pig4cloud.pig.common.log.config.PigLogProperties" + }, + { + "name": "security.log.max-length", + "type": "java.lang.Integer", + "description": "请求报文最大存储长度", + "sourceType": "com.pig4cloud.pig.common.log.config.PigLogProperties" + } + ], + "hints": [] +} diff --git a/pig-common/pig-common-log/src/main/resources/META-INF/spring.factories b/pig-common/pig-common-log/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 7f7301ba..00000000 --- a/pig-common/pig-common-log/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# https://github.com/spring-projects/spring-boot/issues/31252 -org.springframework.boot.env.EnvironmentPostProcessor=\ - com.pig4cloud.pig.common.log.init.ApplicationLoggerInitializer diff --git a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/component/PigCustomOpaqueTokenIntrospector.java b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/component/PigCustomOpaqueTokenIntrospector.java index c68665dd..4e1bf7a1 100644 --- a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/component/PigCustomOpaqueTokenIntrospector.java +++ b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/component/PigCustomOpaqueTokenIntrospector.java @@ -1,6 +1,7 @@ package com.pig4cloud.pig.common.security.component; import cn.hutool.extra.spring.SpringUtil; +import com.pig4cloud.pig.common.core.constant.SecurityConstants; import com.pig4cloud.pig.common.security.service.PigUser; import com.pig4cloud.pig.common.security.service.PigUserDetailsService; import lombok.RequiredArgsConstructor; @@ -70,7 +71,13 @@ public class PigCustomOpaqueTokenIntrospector implements OpaqueTokenIntrospector catch (Exception ex) { log.error("资源服务器 introspect Token error {}", ex.getLocalizedMessage()); } - return (PigUser) userDetails; + + // 注入客户端信息,方便上下文中获取 + PigUser pigxUser = (PigUser) userDetails; + Objects.requireNonNull(pigxUser) + .getAttributes() + .put(SecurityConstants.CLIENT_ID, oldAuthorization.getRegisteredClientId()); + return pigxUser; } } diff --git a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigUser.java b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigUser.java index 36f48f9e..67adc583 100755 --- a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigUser.java +++ b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigUser.java @@ -36,6 +36,11 @@ public class PigUser extends User implements OAuth2AuthenticatedPrincipal { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + /** + * 扩展属性,方便存放oauth 上下文相关信息 + */ + private final Map attributes = new HashMap<>(); + /** * 用户ID */ @@ -71,7 +76,7 @@ public class PigUser extends User implements OAuth2AuthenticatedPrincipal { */ @Override public Map getAttributes() { - return new HashMap<>(); + return this.attributes; } @Override diff --git a/pig-common/pig-common-xss/src/main/resources/META-INF/spring-configuration-metadata.json b/pig-common/pig-common-xss/src/main/resources/META-INF/spring-configuration-metadata.json new file mode 100644 index 00000000..638e1e14 --- /dev/null +++ b/pig-common/pig-common-xss/src/main/resources/META-INF/spring-configuration-metadata.json @@ -0,0 +1,58 @@ +{ + "groups": [ + { + "name": "security.xss", + "type": "com.pig4cloud.pig.common.xss.config.PigXssProperties", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties" + } + ], + "properties": [ + { + "name": "security.xss.enable-escape", + "type": "java.lang.Boolean", + "description": "[clear 专用] 使用转义,默认关闭", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties", + "defaultValue": false + }, + { + "name": "security.xss.enabled", + "type": "java.lang.Boolean", + "description": "开启xss", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties", + "defaultValue": true + }, + { + "name": "security.xss.mode", + "type": "com.pig4cloud.pig.common.xss.config.PigXssProperties$Mode", + "description": "模式:clear 清理(默认),escape 转义", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties" + }, + { + "name": "security.xss.path-exclude-patterns", + "type": "java.util.List", + "description": "放行的路由,默认为空", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties" + }, + { + "name": "security.xss.path-patterns", + "type": "java.util.List", + "description": "拦截的路由,默认为空", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties" + }, + { + "name": "security.xss.pretty-print", + "type": "java.lang.Boolean", + "description": "[clear 专用] prettyPrint,默认关闭: 保留换行", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties", + "defaultValue": false + }, + { + "name": "security.xss.trim-text", + "type": "java.lang.Boolean", + "description": "全局:对文件进行首尾 trim", + "sourceType": "com.pig4cloud.pig.common.xss.config.PigXssProperties", + "defaultValue": true + } + ], + "hints": [] +} \ No newline at end of file