diff --git a/pigx-boot/Dockerfile b/pigx-boot/Dockerfile new file mode 100755 index 000000000..4a6d9635d --- /dev/null +++ b/pigx-boot/Dockerfile @@ -0,0 +1,13 @@ +FROM alibabadragonwell/dragonwell:21-anolis + +WORKDIR /pigx-boot + +ARG JAR_FILE=target/pigx-boot.jar + +COPY ${JAR_FILE} app.jar + +EXPOSE 9999 + +ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom" + +CMD sleep 60; java $JAVA_OPTS -jar app.jar diff --git a/pigx-boot/pom.xml b/pigx-boot/pom.xml new file mode 100755 index 000000000..b204345dc --- /dev/null +++ b/pigx-boot/pom.xml @@ -0,0 +1,124 @@ + + + + + 4.0.0 + + com.pig4cloud + pigx + 5.4.0 + + + pigx-boot + jar + + pigx 单体版本启动 + + + + + com.pig4cloud + pigx-auth + ${project.version} + + + + com.pig4cloud + pigx-upms-biz + ${project.version} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.pig4cloud + pigx-common-security + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + io.springboot + knife4j-boot-openapi3-ui + ${knife4j.version} + + + + com.pig4cloud + pigx-common-swagger + + + + org.springframework.boot + spring-boot-starter-undertow + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + io.fabric8 + docker-maven-plugin + + + + diff --git a/pigx-boot/src/main/java/com/pig4cloud/pigx/PigxBootApplication.java b/pigx-boot/src/main/java/com/pig4cloud/pigx/PigxBootApplication.java new file mode 100755 index 000000000..e1656d6ff --- /dev/null +++ b/pigx-boot/src/main/java/com/pig4cloud/pigx/PigxBootApplication.java @@ -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); + } + +} diff --git a/pigx-boot/src/main/java/com/pig4cloud/pigx/bootstrap/PigxBootSecurityServerConfiguration.java b/pigx-boot/src/main/java/com/pig4cloud/pigx/bootstrap/PigxBootSecurityServerConfiguration.java new file mode 100644 index 000000000..76b017673 --- /dev/null +++ b/pigx-boot/src/main/java/com/pig4cloud/pigx/bootstrap/PigxBootSecurityServerConfiguration.java @@ -0,0 +1,159 @@ +/* + * + * 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; + +/** + * @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.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class); + // 增加密码解密过滤器 + http.addFilterBefore(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class); + + // 认证服务器配置 + http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点 + tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter) // 注入自定义的授权认证Converter + .accessTokenResponseHandler(successEventHandler) // 登录成功处理器 + .errorResponseHandler(failureEventHandler);// 登录失败处理器 + }).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证 + oAuth2ClientAuthenticationConfigurer.errorResponseHandler(failureEventHandler))// 处理客户端认证异常 + , Customizer.withDefaults()) + .with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现 + .authorizationServerSettings( + AuthorizationServerSettings.builder().issuer(SecurityConstants.PIGX_LICENSE).build()), + Customizer.withDefaults()); + + // 资源服务器配置 + AntPathRequestMatcher[] requestMatchers = permitAllUrl.getIgnoreUrls() + .stream() + .map(AntPathRequestMatcher::new) + .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); + + http.with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现 + .authorizationServerSettings( + AuthorizationServerSettings.builder().issuer(SecurityConstants.PIGX_LICENSE).build()), + Customizer.withDefaults()); + + DefaultSecurityFilterChain securityFilterChain = http.build(); + + // 注入自定义授权模式实现 + addCustomOAuth2GrantAuthenticationProvider(http); + return securityFilterChain; + } + + /** + * 注入授权模式实现提供方 + *

+ * 1. 密码模式
+ * 2. 短信登录
+ */ + @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); + } + +} diff --git a/pigx-boot/src/main/resources/application-dev.yml b/pigx-boot/src/main/resources/application-dev.yml new file mode 100644 index 000000000..535108b14 --- /dev/null +++ b/pigx-boot/src/main/resources/application-dev.yml @@ -0,0 +1,39 @@ +spring: + data: + 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 diff --git a/pigx-boot/src/main/resources/application.yml b/pigx-boot/src/main/resources/application.yml new file mode 100644 index 000000000..34a7ccaa3 --- /dev/null +++ b/pigx-boot/src/main/resources/application.yml @@ -0,0 +1,65 @@ +server: + port: 9999 + servlet: + context-path: /admin + +spring: + application: + name: @project.artifactId@ + # 缓存相关配置 + cache: + type: redis + # 上传文件大小限制 + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + cloud: + nacos: + config: + enabled: false + discovery: + enabled: false + gateway: + enabled: false + main: + allow-bean-definition-overriding: true + profiles: + active: dev + +## 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 + global-config: + banner: false + db-config: + id-type: auto + where-strategy: not_empty + insert-strategy: not_empty + update-strategy: not_null + type-handlers-package: com.pig4cloud.pigx.common.data.handler + configuration: + jdbc-type-for-null: 'null' + call-setters-on-nulls: true + shrink-whitespaces-in-sql: true +mybatis-plus-join: + banner: false