♻️ 重构单体版本,支持一套代码支持两种登录模式

This commit is contained in:
冷冷 committed 2024-04-23 09:25:16 +08:00
1 parent 4bd449c53b
commit 078adf7d67
78 files changed
+1497 -1132

No files matched your search

+2 -2
View File
@@ -33,10 +33,10 @@ CREATE TABLE `config_info` (
-- ----------------------------
BEGIN;
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (1, 'application-dev.yml', 'DEFAULT_GROUP', '# 配置文件加密根密码\njasypt:\n encryptor:\n password: pigx\n algorithm: PBEWithMD5AndDES\n iv-generator-classname: org.jasypt.iv.NoIvGenerator\n\n\nspring:\n redis:\n host: pigx-redis\n servlet:\n multipart:\n max-file-size: 100MB\n max-request-size: 100MB\n cloud:\n sentinel:\n eager: true\n transport:\n dashboard: pigx-sentinel:5020\n openfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n connection-timeout: 20000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\n# 端点对外暴露\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\' \n endpoint:\n restart:\n enabled: true\n health:\n show-details: ALWAYS\n\n#开启灰度\ngray:\n rule:\n enabled: true\n\n# mybatis-plus 配置\nmybatis-plus:\n tenant-enable: ture\n mapper-locations: classpath:/mapper/*Mapper.xml\n global-config:\n capitalMode: true\n banner: false\n db-config:\n id-type: auto\n select-strategy: not_empty\n insert-strategy: not_empty\n update-strategy: not_null\n type-handlers-package: com.pig4cloud.pigx.common.data.handler\n configuration:\n jdbc-type-for-null: \'null\'\n call-setters-on-nulls: true\n shrink-whitespaces-in-sql: true\nmybatis-plus-join:\n banner: false #关闭连表查询组件banner', '93aac2c7c8b710561d18211674533426', '2022-12-16 10:44:25', '2024-02-27 11:57:02', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (2, 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/', '74f53b71c7799aa754da75662378b93c', '2022-12-16 10:44:25', '2022-12-16 10:44:25', NULL, '0:0:0:0:0:0:0:1', '', '', NULL, NULL, NULL, 'yaml', NULL, '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (2, 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/\n\n# 前端登录验证码\nsecurity:\n encodeKey: \'pigxpigxpigxpigx\'\n# 验证码相关配置参考: http://t.cn/A647jEdu\naj:\n captcha:\n cache-type: redis\n water-mark: pig4cloud', 'bb6bd9b9e21afdec3d6c88636387df96', '2022-12-16 10:44:25', '2024-04-20 22:47:21', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (3, 'pigx-codegen-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_codegen}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n', 'ed6de06e34e2634c28a24e8a1db99b06', '2022-12-16 10:44:25', '2024-02-22 15:08:09', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (4, 'pigx-daemon-elastic-job-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true', '09996f46e0b80d7b2aa320ef4cb31c82', '2022-12-16 10:44:25', '2023-04-07 14:14:50', 'nacos', '127.0.0.1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (5, 'pigx-gateway-dev.yml', 'DEFAULT_GROUP', 'gateway:\n encode-key: \'pigxpigxpigxpigx\'\n\n# 验证码相关配置参考: http://t.cn/A647jEdu\naj:\n captcha:\n cache-type: redis\n water-mark: pig4cloud\n\n# 固定路由转发配置 无修改\nspring:\n cloud:\n gateway:\n routes:\n - id: openapi\n uri: lb://pigx-gateway\n predicates:\n - Path=/v3/api-docs/**\n filters:\n - RewritePath=/v3/api-docs/(?<path>.*), /$\\{path}/$\\{path}/v3/api-docs\n\n# gateway 刷新端点\nmanagement:\n endpoint:\n gateway:\n enabled: true\n', 'd138f5bafa91ab76dca8c4c1a01c1de2', '2022-12-16 10:44:25', '2023-07-28 16:49:29', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (5, 'pigx-gateway-dev.yml', 'DEFAULT_GROUP', '# 固定路由转发配置 无修改\nspring:\n cloud:\n gateway:\n routes:\n - id: openapi\n uri: lb://pigx-gateway\n predicates:\n - Path=/v3/api-docs/**\n filters:\n - RewritePath=/v3/api-docs/(?<path>.*), /$\\{path}/$\\{path}/v3/api-docs\n\n# gateway 刷新端点\nmanagement:\n endpoint:\n gateway:\n enabled: true\n', 'd9454d877ff3d8bd3fd0d5be99810195', '2022-12-16 10:44:25', '2024-04-20 22:47:02', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (6, 'pigx-monitor-dev.yml', 'DEFAULT_GROUP', 'spring:\n # 安全配置\n security:\n user:\n name: ENC(rZHA4LW5hHmhLAAzJoFNag==) # pigx\n password: ENC(bjeyh+Aeii3kHXkoo00ZUw==) # pigx\n autoconfigure:\n exclude: com.pig4cloud.pigx.common.core.config.JacksonConfiguration\n boot:\n admin:\n ui:\n title: \'pigx 服务状态监控\'\n brand: \'pigx 服务状态监控\'\n external-views:\n - label: \"SQL监控\"\n url: /druid/sql.html\n order: 2000\n iframe: true\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n endpoint:\n health:\n show-details: ALWAYS #显示详细信息\n\n\n# druid 监控的服务\nmonitor:\n applications:\n - pigx-upms-biz\n', '2bb39e4dee3f90d4186d1e42aa666d2a', '2022-12-16 10:44:25', '2023-04-07 14:12:09', 'nacos', '127.0.0.1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (7, 'pigx-upms-biz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n ignore-urls:\n - /druid/**\n\n# 数据源\nspring:\n autoconfigure:\n exclude: org.springframework.cloud.gateway.config.GatewayAutoConfiguration,org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n stat-view-servlet:\n enabled: true\n allow: \"\"\n url-pattern: /druid/*\n #login-username: admin\n #login-password: admin\n filter:\n stat:\n enabled: true\n log-slow-sql: true\n slow-sql-millis: 10000\n merge-sql: false\n wall:\n config:\n multi-statement-allow: true\n\n# 本地文件系统\nfile:\n local:\n enable: true\n basePath: /Users/lengleng/Downloads/files', '28f2305c1cfb413dcc45a3d432ef7098', '2022-12-16 10:44:25', '2024-02-22 15:08:36', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '', '');
INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_create`, `gmt_modified`, `src_user`, `src_ip`, `app_name`, `tenant_id`, `c_desc`, `c_use`, `effect`, `type`, `c_schema`, `encrypted_data_key`) VALUES (8, 'pigx-daemon-quartz-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/', '79619124a30cdb6e8bc1046aaa18d91c', '2022-12-16 10:44:25', '2024-04-19 21:49:00', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '', '');
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-app-server</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-app-server-api</artifactId>
+23 -14
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-app-server</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-app-server-biz</artifactId>
@@ -62,7 +62,7 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-app-server-api</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<!--必备: log 依赖-->
<dependency>
@@ -90,16 +90,25 @@
<artifactId>pigx-common-swagger</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-app-server</artifactId>
+38 -24
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-auth</artifactId>
@@ -78,6 +78,23 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 加签 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
</dependency>
<!-- 调用验证码核心模块 -->
<dependency>
<groupId>io.springboot.plugin</groupId>
<artifactId>captcha-core</artifactId>
<version>${captcha.image.version}</version>
</dependency>
<!--滑块验证码-->
<dependency>
<groupId>com.github.anji-plus</groupId>
<artifactId>captcha-spring-boot-starter</artifactId>
<version>${captcha.version}</version>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -90,27 +107,24 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -20,6 +20,8 @@ import com.pig4cloud.pigx.auth.support.CustomeOAuth2AccessTokenGenerator;
import com.pig4cloud.pigx.auth.support.core.CustomeOAuth2TokenCustomizer;
import com.pig4cloud.pigx.auth.support.core.FormIdentityLoginConfigurer;
import com.pig4cloud.pigx.auth.support.core.PigxDaoAuthenticationProvider;
import com.pig4cloud.pigx.auth.support.filter.PasswordDecoderFilter;
import com.pig4cloud.pigx.auth.support.filter.ValidateCodeFilter;
import com.pig4cloud.pigx.auth.support.handler.PigxAuthenticationFailureEventHandler;
import com.pig4cloud.pigx.auth.support.handler.PigxAuthenticationSuccessEventHandler;
import com.pig4cloud.pigx.auth.support.password.OAuth2ResourceOwnerPasswordAuthenticationConverter;
@@ -30,6 +32,7 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.security.handler.FormAuthenticationFailureHandler;
import com.pig4cloud.pigx.common.security.handler.SsoLogoutSuccessHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@@ -47,6 +50,7 @@ import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import java.util.Arrays;
@@ -63,12 +67,22 @@ public class AuthorizationServerConfiguration {
private final OAuth2AuthorizationService authorizationService;
private final PasswordDecoderFilter passwordDecoderFilter;
private final ValidateCodeFilter validateCodeFilter;
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnProperty(value = "security.micro", matchIfMissing = true)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http,
PigxAuthenticationSuccessEventHandler successEventHandler,
PigxAuthenticationFailureEventHandler failureEventHandler) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
// 增加验证码过滤器
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
// 增加密码解密过滤器
http.addFilterBefore(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) // 注入自定义的授权认证Converter
@@ -81,7 +95,7 @@ public class AuthorizationServerConfiguration {
DefaultSecurityFilterChain securityFilterChain = http.authorizeHttpRequests(authorizeRequests -> {
// 自定义接口、端点暴露
authorizeRequests.antMatchers("/token/**", "/actuator/**", "/css/**", "/error").permitAll();
authorizeRequests.antMatchers("/token/**","/code/**", "/actuator/**", "/css/**", "/error").permitAll();
authorizeRequests.anyRequest().authenticated();
}).apply(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
.authorizationServerSettings(
@@ -121,7 +135,8 @@ public class AuthorizationServerConfiguration {
* request -> xToken 注入请求转换器
* @return DelegatingAuthenticationConverter
*/
private AuthenticationConverter accessTokenRequestConverter() {
@Bean
public AuthenticationConverter accessTokenRequestConverter() {
return new DelegatingAuthenticationConverter(Arrays.asList(
new OAuth2ResourceOwnerPasswordAuthenticationConverter(),
new OAuth2ResourceOwnerSmsAuthenticationConverter(), new OAuth2RefreshTokenAuthenticationConverter(),
@@ -1,4 +1,4 @@
package com.pig4cloud.pigx.gateway.config;
package com.pig4cloud.pigx.auth.endpoint;
import com.anji.captcha.service.CaptchaCacheService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -0,0 +1,84 @@
package com.pig4cloud.pigx.auth.endpoint;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import io.springboot.captcha.ArithmeticCaptcha;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
/**
* 验证码相关的接口
*
* @author lengleng
* @date 2022/6/27
*/
@RestController
@RequestMapping("/code")
@RequiredArgsConstructor
public class ImageCodeEndpoint {
private static final Integer DEFAULT_IMAGE_WIDTH = 100;
private static final Integer DEFAULT_IMAGE_HEIGHT = 40;
private final StringRedisTemplate redisTemplate;
/**
* 创建图形验证码
*/
@SneakyThrows
@GetMapping("/image")
public void image(String randomStr, HttpServletResponse response) {
ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
String result = captcha.text();
redisTemplate.opsForValue()
.set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
// 转换流信息写出
captcha.out(response.getOutputStream());
}
/**
* 行为
* 创建滑块图形验证码
*/
@SneakyThrows
@GetMapping("/create")
public R behavior() {
CaptchaVO vo = new CaptchaVO();
vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE);
CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class);
return R.ok(captchaService.get(vo));
}
/**
* 行为
* 创建滑块图形验证码
*/
@SneakyThrows
@PostMapping("/check")
public R check(HttpServletRequest request) {
CaptchaVO vo = new CaptchaVO();
vo.setPointJson(request.getParameter("pointJson"));
vo.setToken(request.getParameter("token"));
vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE);
CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class);
return R.ok(captchaService.check(vo));
}
}
@@ -0,0 +1,30 @@
package com.pig4cloud.pigx.auth.support.filter;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2020/10/4
* <p>
* 网关配置文件
*/
@Data
@Component
@RefreshScope
@ConfigurationProperties("security")
public class AuthSecurityConfigProperties {
/**
* 是否是微服务架构
*/
private boolean isMicro;
/**
* 网关解密登录前端密码 秘钥
*/
private String encodeKey;
}
@@ -0,0 +1,139 @@
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.pigx.auth.support.filter;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.EncFlagTypeEnum;
import com.pig4cloud.pigx.common.core.util.RepeatBodyRequestWrapper;
import com.pig4cloud.pigx.common.core.util.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.util.Map;
/**
* @author lengleng
* @date 2019 /2/1 密码解密工具类
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class PasswordDecoderFilter extends OncePerRequestFilter {
private final AuthSecurityConfigProperties authSecurityConfigProperties;
private final StringRedisTemplate redisTemplate;
private static final String PASSWORD = "password";
private static final String KEY_ALGORITHM = "AES";
static {
// 关闭hutool 强制关闭Bouncy Castle库的依赖
SecureUtil.disableBouncyCastle();
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
// 不是登录请求,直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getRequestURI(), SecurityConstants.OAUTH_TOKEN_URL)) {
chain.doFilter(request, response);
return;
}
// 2. 刷新token类型,直接向下执行
String grantType = request.getParameter("grant_type");
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
chain.doFilter(request, response);
return;
}
// 3. 判断客户端是否需要解密,明文传输直接向下执行
if (!isEncClient(request)) {
chain.doFilter(request, response);
return; }
// 将请求流转换为可多次读取的请求流
RepeatBodyRequestWrapper requestWrapper = new RepeatBodyRequestWrapper(request);
Map<String, String[]> parameterMap = requestWrapper.getParameterMap();
// 构建前端对应解密AES 因子
AES aes = new AES(Mode.CFB, Padding.NoPadding,
new SecretKeySpec(authSecurityConfigProperties.getEncodeKey().getBytes(), KEY_ALGORITHM),
new IvParameterSpec(authSecurityConfigProperties.getEncodeKey().getBytes()));
parameterMap.forEach((k, v) -> {
String[] values = parameterMap.get(k);
if (!PASSWORD.equals(k) || ArrayUtil.isEmpty(values)) {
return;
}
// 解密密码
String decryptPassword = aes.decryptStr(values[0]);
parameterMap.put(k, new String[]{decryptPassword});
});
chain.doFilter(requestWrapper, response);
}
/**
* 根据请求的clientId 查询客户端配置是否是加密传输
*
* @param request 请求上下文
* @return true 加密传输 、 false 原文传输
*/
private boolean isEncClient(HttpServletRequest request) {
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
String clientId = WebUtils.extractClientId(header).orElse(null);
// 获取租户拼接区分租户的key
String tenantId = request.getHeader(CommonConstants.TENANT_ID);
String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId,
CacheConstants.CLIENT_FLAG, clientId);
String val = redisTemplate.opsForValue().get(key);
// 当配置不存在时,默认需要解密
if (val == null) {
return true;
}
JSONObject information = JSONUtil.parseObj(val);
return !StrUtil.equals(EncFlagTypeEnum.NO.getType(), information.getStr(CommonConstants.ENC_FLAG));
}
}
@@ -0,0 +1,179 @@
package com.pig4cloud.pigx.auth.support.filter;
/**
* 登录前处理器
*
* @author lengleng
* @date 2024/4/3
*/
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.CaptchaFlagTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ValidateCodeException;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.core.util.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
/**
* @author lbw
* @date 2024-01-06
* <p>
* 登录前置处理器: 前端密码传输密文解密,验证码处理
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class ValidateCodeFilter extends OncePerRequestFilter {
private final StringRedisTemplate redisTemplate;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String requestUrl = request.getServletPath();
// 不是登录URL 请求直接跳过
if (!SecurityConstants.OAUTH_TOKEN_URL.equals(requestUrl)) {
filterChain.doFilter(request, response);
return;
}
// 如果登录URL 但是刷新token的请求,直接向下执行
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
if (StrUtil.containsAny(grantType, SecurityConstants.REFRESH_TOKEN)) {
filterChain.doFilter(request, response);
return;
}
// mobile模式, 如果请求不包含mobile 参数直接
String mobile = request.getParameter(SecurityConstants.GRANT_MOBILE);
if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && StrUtil.isBlank(mobile)) {
throw new OAuth2AuthenticationException(SecurityConstants.GRANT_MOBILE);
}
// mobile模式, 社交登录模式不校验验证码直接跳过
if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && !StrUtil.contains(mobile, "SMS")) {
filterChain.doFilter(request, response);
return;
}
// 判断客户端是否跳过检验
if (!isCheckCaptchaClient(request)) {
filterChain.doFilter(request, response);
return;
}
// 校验验证码 1. 客户端开启验证码 2. 短信模式
try {
checkCode();
filterChain.doFilter(request, response);
} catch (ValidateCodeException validateCodeException) {
throw new OAuth2AuthenticationException(validateCodeException.getMessage());
}
}
/**
* 校验验证码
*/
private void checkCode() throws ValidateCodeException {
HttpServletRequest request = WebUtils.getRequest();
String code = request.getParameter("code");
if (StrUtil.isBlank(code)) {
throw new ValidateCodeException("验证码不能为空");
}
String randomStr = request.getParameter("randomStr");
// https://gitee.com/log4j/pig/issues/IWA0D
String mobile = request.getParameter("mobile");
if (StrUtil.isNotBlank(mobile)) {
randomStr = mobile;
}
// 若是滑块登录
if (CommonConstants.IMAGE_CODE_TYPE.equalsIgnoreCase(randomStr)) {
CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class);
CaptchaVO vo = new CaptchaVO();
vo.setCaptchaVerification(code);
vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE);
if (!captchaService.verification(vo).isSuccess()) {
throw new ValidateCodeException("验证码不能为空");
}
return;
}
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
if (Boolean.FALSE.equals(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);
}
/**
* 是否需要校验客户端,根据client 查询客户端配置
*
* @param request 请求
* @return true 需要校验, false 不需要校验
*/
private boolean isCheckCaptchaClient(HttpServletRequest request) {
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
String clientId = WebUtils.extractClientId(header).orElse(null);
// 获取租户拼接区分租户的key
String tenantId = request.getHeader(CommonConstants.TENANT_ID);
String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId,
CacheConstants.CLIENT_FLAG, clientId);
String val = redisTemplate.opsForValue().get(key);
// 当配置不存在时,不用校验
if (val == null) {
return false;
}
JSONObject information = JSONUtil.parseObj(val);
return !StrUtil.equals(CaptchaFlagTypeEnum.OFF.getType(), information.getStr(CommonConstants.CAPTCHA_FLAG));
}
}
@@ -163,12 +163,6 @@ public class PigxAuthenticationFailureEventHandler implements AuthenticationFail
errorMessage = exception.getLocalizedMessage();
}
// 手机号登录
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
if (SecurityConstants.APP.equals(grantType)) {
errorMessage = MsgUtils.getSecurityMessage("AbstractUserDetailsAuthenticationProvider.smsBadCredentials");
}
this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse);
}
@@ -0,0 +1 @@
com.pig4cloud.pigx.auth.endpoint.CaptchaCacheServiceProvider
+115
View File
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ 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.
-->
<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>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-boot</artifactId>
<packaging>jar</packaging>
<description>pigx 单体版本启动</description>
<dependencies>
<!--必备:认证中心模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-auth</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<!--必备:用户管理模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-upms-biz</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<!--可选:代码生成模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-codegen</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-daemon-quartz</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-daemon-elastic-job</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-mp-platform</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-pay-platform</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-app-server-biz</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<!--安全模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-security</artifactId>
</dependency>
<!-- 接口文档UI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
</dependency>
<dependency>
<groupId>io.springboot</groupId>
<artifactId>knife4j-boot-openapi3-ui</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!--接口文档-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-swagger</artifactId>
</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>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.pigx;
import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer;
import com.pig4cloud.pigx.common.swagger.annotation.EnableOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author lengleng 单体版本启动器,只需要运行此模块则整个系统启动
*/
@EnableOpenApi(value = "admin", isMicro = false)
@EnablePigxResourceServer
@SpringBootApplication
public class PigxBootApplication {
public static void main(String[] args) {
SpringApplication.run(PigxBootApplication.class, args);
}
}
@@ -0,0 +1,154 @@
/*
*
* 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.bootstrap;
import com.pig4cloud.pigx.auth.support.core.PigxDaoAuthenticationProvider;
import com.pig4cloud.pigx.auth.support.filter.PasswordDecoderFilter;
import com.pig4cloud.pigx.auth.support.filter.ValidateCodeFilter;
import com.pig4cloud.pigx.auth.support.handler.PigxAuthenticationFailureEventHandler;
import com.pig4cloud.pigx.auth.support.handler.PigxAuthenticationSuccessEventHandler;
import com.pig4cloud.pigx.auth.support.password.OAuth2ResourceOwnerPasswordAuthenticationProvider;
import com.pig4cloud.pigx.auth.support.sms.OAuth2ResourceOwnerSmsAuthenticationProvider;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.security.component.PermitAllUrlProperties;
import com.pig4cloud.pigx.common.security.component.PigxBearerTokenExtractor;
import com.pig4cloud.pigx.common.security.component.ResourceAuthExceptionEntryPoint;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.util.stream.Collectors;
/**
* @author lengleng 认证授权服务器配置
*/
@Configuration
@RequiredArgsConstructor
public class PigxBootSecurityServerConfiguration {
private final ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;
private final OpaqueTokenIntrospector customOpaqueTokenIntrospector;
private final AuthenticationConverter accessTokenRequestConverter;
private final OAuth2AuthorizationService authorizationService;
private final PigxBearerTokenExtractor pigBearerTokenExtractor;
private final PasswordDecoderFilter passwordDecoderFilter;
private final OAuth2TokenGenerator oAuth2TokenGenerator;
private final ValidateCodeFilter validateCodeFilter;
private final PermitAllUrlProperties permitAllUrl;
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http,
PigxAuthenticationSuccessEventHandler successEventHandler,
PigxAuthenticationFailureEventHandler failureEventHandler) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
http.addFilterAfter(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
http.apply(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter) // 注入自定义的授权认证Converter
.accessTokenResponseHandler(successEventHandler) // 登录成功处理器
.errorResponseHandler(failureEventHandler);// 登录失败处理器
}).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
oAuth2ClientAuthenticationConfigurer.errorResponseHandler(failureEventHandler))// 处理客户端认证异常
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
.consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)))
.authorizationService(authorizationService)
.authorizationServerSettings(
AuthorizationServerSettings.builder().issuer(SecurityConstants.PIGX_LICENSE).build());
AntPathRequestMatcher[] requestMatchers = permitAllUrl.getIgnoreUrls()
.stream()
.map(AntPathRequestMatcher::new)
.collect(Collectors.toList())
.toArray(new AntPathRequestMatcher[]{});
http.authorizeHttpRequests(authorizeRequests -> authorizeRequests.requestMatchers(requestMatchers)
.permitAll()
.anyRequest()
.authenticated())
.oauth2ResourceServer(
oauth2 -> oauth2.opaqueToken(token -> token.introspector(customOpaqueTokenIntrospector))
.authenticationEntryPoint(resourceAuthExceptionEntryPoint)
.bearerTokenResolver(pigBearerTokenExtractor))
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(resourceAuthExceptionEntryPoint))
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.csrf(AbstractHttpConfigurer::disable);
DefaultSecurityFilterChain securityFilterChain = http.build();
// 注入自定义授权模式实现
addCustomOAuth2GrantAuthenticationProvider(http);
return securityFilterChain;
}
/**
* 注入授权模式实现提供方
* <p>
* 1. 密码模式 </br>
* 2. 短信登录 </br>
*/
@SuppressWarnings("unchecked")
private void addCustomOAuth2GrantAuthenticationProvider(HttpSecurity http) {
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
OAuth2AuthorizationService authorizationService = http.getSharedObject(OAuth2AuthorizationService.class);
OAuth2ResourceOwnerPasswordAuthenticationProvider resourceOwnerPasswordAuthenticationProvider = new OAuth2ResourceOwnerPasswordAuthenticationProvider(
authenticationManager, authorizationService, oAuth2TokenGenerator);
OAuth2ResourceOwnerSmsAuthenticationProvider resourceOwnerSmsAuthenticationProvider = new OAuth2ResourceOwnerSmsAuthenticationProvider(
authenticationManager, authorizationService, oAuth2TokenGenerator);
// 处理 UsernamePasswordAuthenticationToken
http.authenticationProvider(new PigxDaoAuthenticationProvider());
// 处理 OAuth2ResourceOwnerPasswordAuthenticationToken
http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider);
// 处理 OAuth2ResourceOwnerSmsAuthenticationToken
http.authenticationProvider(resourceOwnerSmsAuthenticationProvider);
}
}
@@ -0,0 +1,40 @@
spring:
cache:
type: redis
redis:
host: pigx-redis
# 数据库相关配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://pigx-mysql:3306/pigxx_boot?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
# 文件上传配置
file:
local:
enable: true
base-path: /Users/lengleng/Downloads/img
# 验证码配置
aj:
captcha:
water-mark: pig4cloud
cache-type: redis
security:
# 登录报文加密根密钥 ,必须是16位
encodeKey: pigxpigxpigxpigx
# 配置文件加密根密码
jasypt:
encryptor:
password: pigx
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
# swagger 配置
swagger:
token-url: ${swagger.gateway}/admin/oauth2/token
@@ -0,0 +1,61 @@
server:
port: 9999 # 项目端口
servlet:
context-path: /admin # 项目访问路径
spring:
application:
name: @project.artifactId@ # 服务名称,取 pom.xml 中的 artifactId
# 上传文件大小限制
servlet:
multipart:
max-file-size: 100MB # 单个文件最大
max-request-size: 100MB # 接收的最大请求大小
cloud:
nacos: # 单机版本关闭nacos 服务发现和配置管理的能力
config:
enabled: false
discovery:
enabled: false
gateway:
enabled: false
main:
allow-bean-definition-overriding: true # 允许覆盖bean定义
profiles:
active: dev # 激活dev,对应 application-dev.yml
## spring security 对外暴露接口设置(不鉴权直接可访问)
security:
micro: false
oauth2:
client:
ignore-urls:
- /webjars/**
- /v3/api-docs/**
- /doc.html
- /swagger-ui.html
- /swagger-ui/**
- /swagger-resources
- /token/check_token
- /error
- /druid/**
- /actuator/**
- /code/**
#--------------如下配置尽量不要变动-------------
# mybatis-plus 配置
mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml # mapper文件位置
global-config:
banner: false # 是否打印 mybatis-plus banner
db-config:
id-type: auto # 主键类型
where-strategy: not_empty # where 条件策略
insert-strategy: not_empty # 插入策略
update-strategy: not_null # 更新策略
type-handlers-package: com.pig4cloud.pigx.common.data.handler # 类型处理器包
configuration:
jdbc-type-for-null: 'null' # 是否设置字段为null
call-setters-on-nulls: true # 是否调用set方法时传入null值
shrink-whitespaces-in-sql: true # 去掉sql中多余的空格
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
小技巧: 在根pom里面设置统一存放路径,统一管理方便维护
<properties>
<log-path>/Users/lengleng</log-path>
</properties>
1. 其他模块加日志输出,直接copy本文件放在resources 目录即可
2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
-->
<configuration debug="false" scan="false">
<property name="log.path" value="logs/${project.artifactId}"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!--nacos 心跳 INFO 屏蔽-->
<logger name="com.alibaba.nacos" level="OFF">
<appender-ref ref="error"/>
</logger>
<!-- 避免 parse 相关依赖不安装警告-->
<logger name="org.apache.tika.parser.external" level="OFF">
<appender-ref ref="error"/>
</logger>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="DEBUG">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
</root>
</configuration>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-audit</artifactId>
+9 -16
View File
@@ -17,18 +17,18 @@
<description>pigx 公共版本控制</description>
<properties>
<pigx.version>5.4.0</pigx.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<pigx.version>5.5.0-SNAPSHOT</pigx.version>
<mybatis-plus.version>3.5.6</mybatis-plus.version>
<mybatis-plus-join.version>1.4.10</mybatis-plus-join.version>
<dynamic-ds.version>4.3.0</dynamic-ds.version>
<druid.version>1.2.20</druid.version>
<hutool.version>5.8.26</hutool.version>
<hutool.version>5.8.27</hutool.version>
<mysql.connector.version>8.0.33</mysql.connector.version>
<oracle.version>21.3.0.0</oracle.version>
<sqlserver.version>8.4.1.jre8</sqlserver.version>
<dm.version>8.1.2.192</dm.version>
<highgo.version>6.2.0</highgo.version>
<knife4j.version>3.0.3</knife4j.version>
<knife4j.version>3.0.5</knife4j.version>
<springdoc.version>1.6.15</springdoc.version>
<swagger.core.version>2.2.14</swagger.core.version>
<mp.weixin.version>4.4.0</mp.weixin.version>
@@ -302,6 +302,11 @@
<artifactId>swagger-annotations</artifactId>
<version>${swagger.core.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
@@ -442,16 +447,4 @@
</dependency>
</dependencies>
</dependencyManagement>
<!-- 增加云效nexus示例仓库 (演示使用,可自行删除) -->
<distributionManagement>
<repository>
<id>rdc-releases</id>
<url>https://packages.aliyun.com/maven/repository/2161442-release-DcBZC1/</url>
</repository>
<snapshotRepository>
<id>rdc-snapshots</id>
<url>https://packages.aliyun.com/maven/repository/2161442-snapshot-FzKqZK/</url>
</snapshotRepository>
</distributionManagement>
</project>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-core</artifactId>
@@ -0,0 +1,103 @@
/*
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* 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.pigx.common.core.util;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StreamUtils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
/**
* Request包装类:允许 body 重复读取
*
* @author Hccake
*/
@Slf4j
public class RepeatBodyRequestWrapper extends HttpServletRequestWrapper {
private final byte[] bodyByteArray;
private final Map<String, String[]> parameterMap;
public RepeatBodyRequestWrapper(HttpServletRequest request) {
super(request);
this.bodyByteArray = getByteBody(request);
this.parameterMap = super.getParameterMap();
}
@Override
public BufferedReader getReader() {
return ObjectUtils.isEmpty(this.bodyByteArray) ? null
: new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.bodyByteArray);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
// doNoting
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
private static byte[] getByteBody(HttpServletRequest request) {
byte[] body = new byte[0];
try {
body = StreamUtils.copyToByteArray(request.getInputStream());
}
catch (IOException e) {
log.error("解析流中数据异常", e);
}
return body;
}
/**
* 重写 getParameterMap() 方法 解决 undertow 中流被读取后,会进行标记,从而导致无法正确获取 body 中的表单数据的问题
* @return Map<String, String [ ]> parameterMap
*/
@Override
public Map<String, String[]> getParameterMap() {
return this.parameterMap;
}
}
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-data</artifactId>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>pigx-common</artifactId>
<groupId>com.pig4cloud</groupId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-encrypt-api</artifactId>
+33 -5
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-excel</artifactId>
@@ -33,8 +33,9 @@
<description>pigx excel 操作</description>
<properties>
<commons-compress>1.21</commons-compress>
<easyexcel.version>3.1.1</easyexcel.version>
<commons-compress>1.26.1</commons-compress>
<easyexcel.version>3.3.4</easyexcel.version>
<poi.version>5.2.5</poi.version>
</properties>
<dependencies>
@@ -61,16 +62,43 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-lite</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
</project>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -17,7 +17,6 @@
package org.springframework.cloud.openfeign;
import com.pig4cloud.pigx.common.feign.PigxFeignAutoConfiguration;
import lombok.Getter;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
@@ -34,7 +33,6 @@ import org.springframework.core.env.Environment;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
@@ -47,8 +45,7 @@ import java.util.Map;
* <p>
* feign 自动配置功能 from mica
*/
public class PigxFeignClientsRegistrar
implements ImportBeanDefinitionRegistrar, BeanClassLoaderAware, EnvironmentAware {
public class PigxFeignClientsRegistrar implements ImportBeanDefinitionRegistrar, BeanClassLoaderAware, EnvironmentAware {
private final static String BASE_URL = "http://127.0.0.1:${server.port}${server.servlet.context-path}";
@@ -69,11 +66,12 @@ public class PigxFeignClientsRegistrar
}
private void registerFeignClients(BeanDefinitionRegistry registry) {
List<String> feignClients = new ArrayList<>();
List<String> feignClients = new ArrayList<>(
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()));
// 支持 springboot 2.7 + 最新版本的配置方式
ImportCandidates.load(FeignClient.class, getBeanClassLoader()).forEach(feignClients::add);
// 如果 spring.factories 里为空
if (feignClients.isEmpty()) {
return;
@@ -86,16 +84,20 @@ public class PigxFeignClientsRegistrar
if (attributes == null) {
continue;
}
// 如果是单体项目自动注入 & url 为空
Boolean isMicro = environment.getProperty("spring.cloud.nacos.discovery.enabled", Boolean.class, true);
// 如果已经存在该 bean,支持原生的 Feign
if (registry.containsBeanDefinition(className)) {
if (registry.containsBeanDefinition(className) && isMicro) {
continue;
}
registerClientConfiguration(registry, getClientName(attributes), attributes.get("configuration"));
validate(attributes);
BeanDefinitionBuilder definition = BeanDefinitionBuilder
.genericBeanDefinition(FeignClientFactoryBean.class);
definition.addPropertyValue("url", getUrl(attributes));
definition.addPropertyValue("url", getUrl(registry, attributes));
definition.addPropertyValue("path", getPath(attributes));
String name = getName(attributes);
definition.addPropertyValue("name", name);
@@ -149,7 +151,7 @@ public class PigxFeignClientsRegistrar
* @return the factory class
*/
private Class<?> getSpringFactoriesLoaderFactoryClass() {
return PigxFeignAutoConfiguration.class;
return PigxFeignClientsRegistrar.class;
}
private void validate(Map<String, Object> attributes) {
@@ -188,15 +190,17 @@ public class PigxFeignClientsRegistrar
return value;
}
private String getUrl(Map<String, Object> attributes) {
private String getUrl(BeanDefinitionRegistry registry, Map<String, Object> attributes) {
// 如果是单体项目自动注入 & url 为空
String url = (String) attributes.get("url");
boolean present = ClassUtils.isPresent("com.alibaba.cloud.nacos.discovery.NacosDiscoveryClient",
this.getClass().getClassLoader());
if (!StringUtils.hasText(url) && !present) {
url = resolve(BASE_URL);
Boolean isMicro = environment.getProperty("spring.cloud.nacos.discovery.enabled", Boolean.class, true);
if (isMicro) {
return null;
}
String url = resolve(BASE_URL);
return FeignClientsRegistrar.getUrl(url);
}
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-gateway</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-gray</artifactId>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-idempotent</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-job</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-log</artifactId>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-oss</artifactId>
+1 -1
View File
@@ -23,7 +23,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-seata</artifactId>
+1 -1
View File
@@ -23,7 +23,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-security</artifactId>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-sequence</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-swagger</artifactId>
@@ -20,6 +20,12 @@ public class OpenAPIMetadataConfiguration implements InitializingBean, Applicati
@Override
public void afterPropertiesSet() throws Exception {
String[] beanNamesForType = applicationContext.getBeanNamesForType(ServiceInstance.class);
if (beanNamesForType.length == 0) {
return;
}
ServiceInstance serviceInstance = applicationContext.getBean(ServiceInstance.class);
serviceInstance.getMetadata().put("spring-doc", path);
}
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-websocket</artifactId>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common-xss</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-common</artifactId>
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-flow-engine</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-flow-engine-api</artifactId>
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-flow-engine</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-flow-engine-biz</artifactId>
@@ -123,16 +123,24 @@
<artifactId>DmJdbcDriver18</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-flow</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-flow-engine</artifactId>
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-flow-task</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-flow-task-api</artifactId>
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-flow-task</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-flow-task-biz</artifactId>
@@ -103,16 +103,24 @@
<artifactId>DmJdbcDriver18</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-flow</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-flow-task</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-flow</artifactId>
+1 -13
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-gateway</artifactId>
@@ -66,18 +66,6 @@
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--验证码-->
<dependency>
<groupId>com.github.anji-plus</groupId>
<artifactId>captcha-spring-boot-starter</artifactId>
<version>${captcha.version}</version>
</dependency>
<!--图形验证码-->
<dependency>
<groupId>io.springboot.plugin</groupId>
<artifactId>captcha-core</artifactId>
<version>${captcha.image.version}</version>
</dependency>
<!--缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -1,25 +0,0 @@
package com.pig4cloud.pigx.gateway.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2020/10/2
* <p>
* 网关通用配置文件
*/
@Data
@Component
@RefreshScope
@ConfigurationProperties("gateway")
public class GatewayConfigProperties {
/**
* 网关解密登录前端密码 秘钥 {@link com.pig4cloud.pigx.gateway.filter.PasswordDecoderFilter}
*/
public String encodeKey;
}
@@ -1,59 +0,0 @@
/*
* 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.handler.ImageCodeCheckHandler;
import com.pig4cloud.pigx.gateway.handler.ImageCodeCreateHandler;
import com.pig4cloud.pigx.gateway.handler.ImageCodeMathHandler;
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 ImageCodeCheckHandler imageCodeCheckHandler;
private final ImageCodeCreateHandler imageCodeCreateHandler;
private final ImageCodeMathHandler imageCodeMathHandler;
@Bean
public RouterFunction routerFunction() {
return RouterFunctions
.route(RequestPredicates.path("/code/create").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
imageCodeCreateHandler)
.andRoute(RequestPredicates.path("/code/image").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
imageCodeMathHandler)
.andRoute(RequestPredicates.POST("/code/check").and(RequestPredicates.accept(MediaType.ALL)),
imageCodeCheckHandler);
}
}
@@ -1,215 +0,0 @@
/*
* 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.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.EncFlagTypeEnum;
import com.pig4cloud.pigx.common.core.util.WebUtils;
import com.pig4cloud.pigx.gateway.config.GatewayConfigProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* @author lengleng
* @date 2020/1/8 密码解密工具类
* <p>
* 参考 ModifyRequestBodyGatewayFilterFactory 实现
*/
@Slf4j
@Component
@RequiredArgsConstructor
@SuppressWarnings("all")
public class PasswordDecoderFilter extends AbstractGatewayFilterFactory {
private final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();
private static final String PASSWORD = "password";
private static final String KEY_ALGORITHM = "AES";
private final StringRedisTemplate redisTemplate;
private final GatewayConfigProperties gatewayConfig;
static {
// 关闭hutool 强制关闭Bouncy Castle库的依赖
SecureUtil.disableBouncyCastle();
}
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 1. 不是登录请求,直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
return chain.filter(exchange);
}
// 2. 刷新token类型,直接向下执行
String grantType = request.getQueryParams().getFirst("grant_type");
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
return chain.filter(exchange);
}
// 3. 判断客户端是否需要解密,明文传输直接向下执行
if (!isEncClient(request)) {
return chain.filter(exchange);
}
// 4. 前端加密密文解密逻辑
Class inClass = String.class;
Class outClass = String.class;
ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
// 解密生成新的报文
Mono<?> modifiedBody = serverRequest.bodyToMono(inClass).flatMap(decryptAES());
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass);
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
headers.remove(HttpHeaders.CONTENT_LENGTH);
headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
ServerHttpRequest decorator = decorate(exchange, headers, outputMessage);
return chain.filter(exchange.mutate().request(decorator).build());
}));
};
}
/**
* 根据请求的clientId 查询客户端配置是否是加密传输
* @param request 请求上下文
* @return true 加密传输 、 false 原文传输
*/
private boolean isEncClient(ServerHttpRequest request) {
String header = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
String clientId = WebUtils.extractClientId(header).orElse(null);
// 获取租户拼接区分租户的key
String tenantId = request.getHeaders().getFirst(CommonConstants.TENANT_ID);
String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId,
CacheConstants.CLIENT_FLAG, clientId);
String val = redisTemplate.opsForValue().get(key);
// 当配置不存在时,默认需要解密
if (val == null) {
return true;
}
JSONObject information = JSONUtil.parseObj(val);
if (StrUtil.equals(EncFlagTypeEnum.NO.getType(), information.getStr(CommonConstants.ENC_FLAG))) {
return false;
}
return true;
}
/**
* 原文解密
* @return
*/
private Function decryptAES() {
return s -> {
// 构建前端对应解密AES 因子
AES aes = new AES(Mode.CFB, Padding.NoPadding,
new SecretKeySpec(gatewayConfig.getEncodeKey().getBytes(), KEY_ALGORITHM),
new IvParameterSpec(gatewayConfig.getEncodeKey().getBytes()));
// 获取请求密码并解密
Map<String, String> inParamsMap = HttpUtil.decodeParamMap((String) s, CharsetUtil.CHARSET_UTF_8);
if (inParamsMap.containsKey(PASSWORD)) {
String password = aes.decryptStr(inParamsMap.get(PASSWORD));
// 返回修改后报文字符
inParamsMap.put(PASSWORD, password);
}
else {
log.error("非法请求数据:{}", s);
}
// 使用
return Mono.just(HttpUtil.toParams(inParamsMap, Charset.defaultCharset(), true));
};
}
/**
* 报文转换
* @return
*/
private ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers,
CachedBodyOutputMessage outputMessage) {
return new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public HttpHeaders getHeaders() {
long contentLength = headers.getContentLength();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(super.getHeaders());
if (contentLength > 0) {
httpHeaders.setContentLength(contentLength);
}
else {
httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
}
return httpHeaders;
}
@Override
public Flux<DataBuffer> getBody() {
return outputMessage.getBody();
}
};
}
}
@@ -1,199 +0,0 @@
/*
* 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.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.CaptchaFlagTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ValidateCodeException;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.core.util.WebUtils;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* @author lengleng
* @date 2020/5/19 登录逻辑验证码处理
*/
@Slf4j
@Component
@AllArgsConstructor
@SuppressWarnings("all")
public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
private final StringRedisTemplate redisTemplate;
private final ObjectMapper objectMapper;
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 不是登录请求直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
return chain.filter(exchange);
}
// 刷新token,直接向下执行
String grantType = request.getQueryParams().getFirst("grant_type");
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
return chain.filter(exchange);
}
// mobile模式, 如果请求不包含mobile 参数直接
String mobile = request.getQueryParams().getFirst(SecurityConstants.GRANT_MOBILE);
if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && StrUtil.isBlank(mobile)) {
throw new ValidateCodeException();
}
// mobile模式, 社交登录模式不校验验证码直接跳过
if (StrUtil.equals(SecurityConstants.GRANT_MOBILE, grantType) && !StrUtil.contains(mobile, "SMS")) {
return chain.filter(exchange);
}
// 判断客户端是否跳过检验
if (!isCheckCaptchaClient(request)) {
return chain.filter(exchange);
}
try {
// 校验验证码
checkCode(request);
}
catch (Exception e) {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
response.setStatusCode(HttpStatus.PRECONDITION_REQUIRED);
try {
return response.writeWith(Mono.just(
response.bufferFactory().wrap(objectMapper.writeValueAsBytes(R.failed(e.getMessage())))));
}
catch (JsonProcessingException e1) {
log.error("对象输出异常", e1);
}
}
return chain.filter(exchange);
};
}
/**
* 是否需要校验客户端,根据client 查询客户端配置
* @param request 请求
* @return true 需要校验, false 不需要校验
*/
private boolean isCheckCaptchaClient(ServerHttpRequest request) {
String header = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
String clientId = WebUtils.extractClientId(header).orElse(null);
// 获取租户拼接区分租户的key
String tenantId = request.getHeaders().getFirst(CommonConstants.TENANT_ID);
String key = String.format("%s:%s:%s", StrUtil.isBlank(tenantId) ? CommonConstants.TENANT_ID_1 : tenantId,
CacheConstants.CLIENT_FLAG, clientId);
String val = redisTemplate.opsForValue().get(key);
// 当配置不存在时,不用校验
if (val == null) {
return false;
}
JSONObject information = JSONUtil.parseObj(val);
if (StrUtil.equals(CaptchaFlagTypeEnum.OFF.getType(), information.getStr(CommonConstants.CAPTCHA_FLAG))) {
return false;
}
return true;
}
/**
* 检查code
* @param request
*/
@SneakyThrows
private void checkCode(ServerHttpRequest request) {
String code = request.getQueryParams().getFirst("code");
if (StrUtil.isBlank(code)) {
throw new ValidateCodeException("验证码不能为空");
}
String randomStr = request.getQueryParams().getFirst("randomStr");
// 若是滑块登录
if (CommonConstants.IMAGE_CODE_TYPE.equalsIgnoreCase(randomStr)) {
CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class);
CaptchaVO vo = new CaptchaVO();
vo.setCaptchaVerification(code);
vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE);
if (!captchaService.verification(vo).isSuccess()) {
throw new ValidateCodeException("验证码不能为空");
}
return;
}
// https://gitee.com/log4j/pig/issues/IWA0D
String mobile = request.getQueryParams().getFirst("mobile");
if (StrUtil.isNotBlank(mobile)) {
randomStr = mobile;
}
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
if (!redisTemplate.hasKey(key)) {
throw new ValidateCodeException("验证码不合法");
}
String saveCode = redisTemplate.opsForValue().get(key);
if (saveCode == null) {
throw new ValidateCodeException("验证码不合法");
}
if (StrUtil.isBlank(saveCode)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}
if (!StrUtil.equals(saveCode, code)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}
redisTemplate.delete(key);
}
}
@@ -1,65 +0,0 @@
/*
* 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.handler;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
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 2020/5/19 验证码生成逻辑处理类
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class ImageCodeCheckHandler implements HandlerFunction<ServerResponse> {
private final ObjectMapper objectMapper;
@Override
@SneakyThrows
public Mono<ServerResponse> handle(ServerRequest request) {
CaptchaVO vo = new CaptchaVO();
vo.setPointJson(request.queryParam("pointJson").get());
vo.setToken(request.queryParam("token").get());
vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE);
CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class);
ResponseModel responseModel = captchaService.check(vo);
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(objectMapper.writeValueAsString(R.ok(responseModel))));
}
}
@@ -1,62 +0,0 @@
/*
* 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.handler;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
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 2020/5/19 验证码生成逻辑处理类
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class ImageCodeCreateHandler implements HandlerFunction<ServerResponse> {
private final ObjectMapper objectMapper;
@Override
@SneakyThrows
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
CaptchaVO vo = new CaptchaVO();
vo.setCaptchaType(CommonConstants.IMAGE_CODE_TYPE);
CaptchaService captchaService = SpringContextHolder.getBean(CaptchaService.class);
ResponseModel responseModel = captchaService.get(vo);
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(objectMapper.writeValueAsString(R.ok(responseModel))));
}
}
@@ -1,73 +0,0 @@
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.pigx.gateway.handler;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import io.springboot.captcha.ArithmeticCaptcha;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.data.redis.core.StringRedisTemplate;
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 java.util.Optional;
import java.util.concurrent.TimeUnit;
/**
* @author lengleng
* @date 2023-09-29 数据验证码实现
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class ImageCodeMathHandler implements HandlerFunction<ServerResponse> {
private static final Integer DEFAULT_IMAGE_WIDTH = 100;
private static final Integer DEFAULT_IMAGE_HEIGHT = 40;
private final StringRedisTemplate redisTemplate;
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
String result = captcha.text();
// 保存验证码信息
Optional<String> randomStr = serverRequest.queryParam("randomStr");
randomStr.ifPresent(s -> redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + s, result,
SecurityConstants.CODE_TIME, TimeUnit.SECONDS));
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
captcha.out(os);
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.IMAGE_JPEG)
.body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray())));
}
}
+1 -1
View File
@@ -18,7 +18,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-register</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-upms</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-upms-api</artifactId>
@@ -0,0 +1,20 @@
package com.pig4cloud.pigx.admin.api.feign;
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 文件读取
*
* @author lengleng
* @date 2024/3/14
*/
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteFileService {
@GetMapping("/sys-file/oss/file")
Response getFile(@RequestParam String fileName);
}
+22 -22
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-upms</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-upms-biz</artifactId>
@@ -161,27 +161,28 @@
</dependency>
</dependencies>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
@@ -201,5 +202,4 @@
</resource>
</resources>
</build>
</project>
@@ -39,7 +39,7 @@ import java.util.Map;
*/
@RestController
@AllArgsConstructor
@RequestMapping("/token")
@RequestMapping("/sys-token")
@Tag(description = "token", name = "令牌管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysTokenController {
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-upms</artifactId>
+21 -23
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-codegen</artifactId>
@@ -175,26 +175,24 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+21 -23
View File
@@ -23,7 +23,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-daemon-elastic-job</artifactId>
@@ -93,27 +93,25 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+117 -119
View File
@@ -1,126 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
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">
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pigx-daemon-quartz</artifactId>
<packaging>jar</packaging>
<artifactId>pigx-daemon-quartz</artifactId>
<packaging>jar</packaging>
<description>基于quartz后台跑批定时任务模块</description>
<description>基于quartz后台跑批定时任务模块</description>
<dependencies>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--日志处理-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-log</artifactId>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-data</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--数据库-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!--mssql-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!-- ojdbc8 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<!--PG-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-swagger</artifactId>
</dependency>
<!--spring security 、oauth、jwt依赖-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-security</artifactId>
</dependency>
<!-- sentinel-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sentinel</artifactId>
</dependency>
<!--灰度支持-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-gray</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!-- quartz 模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
</dependencies>
<dependencies>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--日志处理-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-log</artifactId>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-data</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--数据库-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!--mssql-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!-- ojdbc8 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<!--PG-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-swagger</artifactId>
</dependency>
<!--spring security 、oauth、jwt依赖-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-security</artifactId>
</dependency>
<!-- sentinel-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sentinel</artifactId>
</dependency>
<!--灰度支持-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-gray</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!-- quartz 模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-jimu-platform</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-monitor</artifactId>
+21 -23
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-mp-platform</artifactId>
@@ -115,26 +115,24 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+21 -23
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-pay-platform</artifactId>
@@ -141,26 +141,24 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-report-platform</artifactId>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pigx-seata-server</artifactId>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-sentinel-dashboard</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-xxl-job-admin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
</parent>
<artifactId>pigx-visual</artifactId>
+10 -38
View File
@@ -24,7 +24,7 @@
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>5.4.0</version>
<version>5.5.0-SNAPSHOT</version>
<name>${project.artifactId}</name>
<packaging>pom</packaging>
<organization>
@@ -50,6 +50,7 @@
<dingtalk.old.version>2.0.0</dingtalk.old.version>
<swagger.fox.version>3.0.0</swagger.fox.version>
<velocity.version>2.3</velocity.version>
<knife4j.version>3.0.5</knife4j.version>
<velocity.tool.version>3.1</velocity.tool.version>
<jasypt.version>3.0.5</jasypt.version>
<ttl.version>2.12.6</ttl.version>
@@ -114,6 +115,7 @@
</dependencies>
<modules>
<module>pigx-boot</module>
<module>pigx-register</module>
<module>pigx-gateway</module>
<module>pigx-auth</module>
@@ -251,45 +253,9 @@
</plugins>
</build>
<!-- 增加云效nexus示例仓库 (演示使用,可自行删除) -->
<distributionManagement>
<repository>
<id>rdc-releases</id>
<url>https://packages.aliyun.com/maven/repository/2161442-release-DcBZC1/</url>
</repository>
<snapshotRepository>
<id>rdc-snapshots</id>
<url>https://packages.aliyun.com/maven/repository/2161442-snapshot-FzKqZK/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<id>dev</id>
<id>cloud</id>
<properties>
<!-- 环境标识,需要与配置文件的名称相对应 -->
<profiles.active>dev</profiles.active>
@@ -301,6 +267,12 @@
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>boot</id>
<modules>
<module>pigx-boot</module>
</modules>
</profile>
</profiles>
</project>