diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/config/AuthorizationServerConfiguration.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/config/AuthorizationServerConfiguration.java index 78ccbfbe8..a0ec586e5 100755 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/config/AuthorizationServerConfiguration.java +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/config/AuthorizationServerConfiguration.java @@ -20,6 +20,8 @@ import com.pig4cloud.pig.auth.support.core.CustomeOAuth2TokenCustomizer; import com.pig4cloud.pig.auth.support.core.FormIdentityLoginConfigurer; import com.pig4cloud.pig.auth.support.core.PigDaoAuthenticationProvider; +import com.pig4cloud.pig.auth.support.filter.PasswordDecoderFilter; +import com.pig4cloud.pig.auth.support.filter.ValidateCodeFilter; import com.pig4cloud.pig.auth.support.handler.PigAuthenticationFailureEventHandler; import com.pig4cloud.pig.auth.support.handler.PigAuthenticationSuccessEventHandler; import com.pig4cloud.pig.auth.support.password.OAuth2ResourceOwnerPasswordAuthenticationConverter; @@ -28,6 +30,7 @@ import com.pig4cloud.pig.auth.support.sms.OAuth2ResourceOwnerSmsAuthenticationProvider; import com.pig4cloud.pig.common.core.constant.SecurityConstants; 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; @@ -45,6 +48,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.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import java.util.Arrays; @@ -52,100 +56,102 @@ /** * @author lengleng * @date 2022/5/27 - * + *

* 认证服务器配置 */ @Configuration @RequiredArgsConstructor public class AuthorizationServerConfiguration { - private final OAuth2AuthorizationService authorizationService; - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer(); - - http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点 - tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) // 注入自定义的授权认证Converter - .accessTokenResponseHandler(new PigAuthenticationSuccessEventHandler()) // 登录成功处理器 - .errorResponseHandler(new PigAuthenticationFailureEventHandler());// 登录失败处理器 - }).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证 - oAuth2ClientAuthenticationConfigurer.errorResponseHandler(new PigAuthenticationFailureEventHandler()))// 处理客户端认证异常 - .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面 - .consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)), Customizer.withDefaults()); - - AntPathRequestMatcher[] requestMatchers = new AntPathRequestMatcher[] { - AntPathRequestMatcher.antMatcher("/token/**"), AntPathRequestMatcher.antMatcher("/actuator/**"), - AntPathRequestMatcher.antMatcher("/css/**"), AntPathRequestMatcher.antMatcher("/error") }; - - http.authorizeHttpRequests(authorizeRequests -> { - // 自定义接口、端点暴露 - authorizeRequests.requestMatchers(requestMatchers).permitAll(); - authorizeRequests.anyRequest().authenticated(); - }) - .with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现 - .authorizationServerSettings( - AuthorizationServerSettings.builder().issuer(SecurityConstants.PROJECT_LICENSE).build()), - Customizer.withDefaults()); - http.with(new FormIdentityLoginConfigurer(), Customizer.withDefaults()); - DefaultSecurityFilterChain securityFilterChain = http.build(); - - // 注入自定义授权模式实现 - addCustomOAuth2GrantAuthenticationProvider(http); - return securityFilterChain; - } - - /** - * 令牌生成规则实现
- * client:username:uuid - * @return OAuth2TokenGenerator - */ - @Bean - public OAuth2TokenGenerator oAuth2TokenGenerator() { - CustomeOAuth2AccessTokenGenerator accessTokenGenerator = new CustomeOAuth2AccessTokenGenerator(); - // 注入Token 增加关联用户信息 - accessTokenGenerator.setAccessTokenCustomizer(new CustomeOAuth2TokenCustomizer()); - return new DelegatingOAuth2TokenGenerator(accessTokenGenerator, new OAuth2RefreshTokenGenerator()); - } - - /** - * request -> xToken 注入请求转换器 - * @return DelegatingAuthenticationConverter - */ - private AuthenticationConverter accessTokenRequestConverter() { - return new DelegatingAuthenticationConverter(Arrays.asList( - new OAuth2ResourceOwnerPasswordAuthenticationConverter(), - new OAuth2ResourceOwnerSmsAuthenticationConverter(), new OAuth2RefreshTokenAuthenticationConverter(), - new OAuth2ClientCredentialsAuthenticationConverter(), - new OAuth2AuthorizationCodeAuthenticationConverter(), - new OAuth2AuthorizationCodeRequestAuthenticationConverter())); - } - - /** - * 注入授权模式实现提供方 - * - * 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 PigDaoAuthenticationProvider()); - // 处理 OAuth2ResourceOwnerPasswordAuthenticationToken - http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider); - // 处理 OAuth2ResourceOwnerSmsAuthenticationToken - http.authenticationProvider(resourceOwnerSmsAuthenticationProvider); - } + 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) 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(new PigAuthenticationSuccessEventHandler()) // 登录成功处理器 + .errorResponseHandler(new PigAuthenticationFailureEventHandler());// 登录失败处理器 + }).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证 + oAuth2ClientAuthenticationConfigurer.errorResponseHandler(new PigAuthenticationFailureEventHandler()))// 处理客户端认证异常 + .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面 + .consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)), Customizer.withDefaults()); + + AntPathRequestMatcher[] requestMatchers = new AntPathRequestMatcher[]{AntPathRequestMatcher.antMatcher("/token/**"), AntPathRequestMatcher.antMatcher("/actuator/**"), AntPathRequestMatcher.antMatcher("/code/image"), AntPathRequestMatcher.antMatcher("/css/**"), AntPathRequestMatcher.antMatcher("/error")}; + + http.authorizeHttpRequests(authorizeRequests -> { + // 自定义接口、端点暴露 + authorizeRequests.requestMatchers(requestMatchers).permitAll(); + authorizeRequests.anyRequest().authenticated(); + }).with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现 + .authorizationServerSettings(AuthorizationServerSettings.builder().issuer(SecurityConstants.PROJECT_LICENSE).build()), Customizer.withDefaults()); + http.with(new FormIdentityLoginConfigurer(), Customizer.withDefaults()); + DefaultSecurityFilterChain securityFilterChain = http.build(); + + // 注入自定义授权模式实现 + addCustomOAuth2GrantAuthenticationProvider(http); + + return securityFilterChain; + } + + /** + * 令牌生成规则实现
+ * client:username:uuid + * + * @return OAuth2TokenGenerator + */ + @Bean + public OAuth2TokenGenerator oAuth2TokenGenerator() { + CustomeOAuth2AccessTokenGenerator accessTokenGenerator = new CustomeOAuth2AccessTokenGenerator(); + // 注入Token 增加关联用户信息 + accessTokenGenerator.setAccessTokenCustomizer(new CustomeOAuth2TokenCustomizer()); + return new DelegatingOAuth2TokenGenerator(accessTokenGenerator, new OAuth2RefreshTokenGenerator()); + } + + /** + * request -> xToken 注入请求转换器 + * + * @return DelegatingAuthenticationConverter + */ + @Bean + public AuthenticationConverter accessTokenRequestConverter() { + return new DelegatingAuthenticationConverter(Arrays.asList(new OAuth2ResourceOwnerPasswordAuthenticationConverter(), new OAuth2ResourceOwnerSmsAuthenticationConverter(), new OAuth2RefreshTokenAuthenticationConverter(), new OAuth2ClientCredentialsAuthenticationConverter(), new OAuth2AuthorizationCodeAuthenticationConverter(), new OAuth2AuthorizationCodeRequestAuthenticationConverter())); + } + + /** + * 注入授权模式实现提供方 + *

+ * 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 PigDaoAuthenticationProvider()); + // 处理 OAuth2ResourceOwnerPasswordAuthenticationToken + http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider); + // 处理 OAuth2ResourceOwnerSmsAuthenticationToken + http.authenticationProvider(resourceOwnerSmsAuthenticationProvider); + } } diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/filter/AuthSecurityConfigProperties.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/filter/AuthSecurityConfigProperties.java new file mode 100644 index 000000000..918be5805 --- /dev/null +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/filter/AuthSecurityConfigProperties.java @@ -0,0 +1,37 @@ +package com.pig4cloud.pig.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; + +import java.util.List; + +/** + * @author lengleng + * @date 2020/10/4 + *

+ * 网关配置文件 + */ +@Data +@Component +@RefreshScope +@ConfigurationProperties("security") +public class AuthSecurityConfigProperties { + + /** + * 是否是微服务架构 + */ + private boolean isMicro; + + /** + * 网关解密登录前端密码 秘钥 + */ + private String encodeKey; + + /** + * 网关不需要校验验证码的客户端 + */ + private List ignoreClients; + +} diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/handler/PigAuthenticationFailureEventHandler.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/handler/PigAuthenticationFailureEventHandler.java index 5c678bc42..71c438c90 100644 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/handler/PigAuthenticationFailureEventHandler.java +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/handler/PigAuthenticationFailureEventHandler.java @@ -19,8 +19,6 @@ import cn.hutool.core.util.StrUtil; import com.pig4cloud.pig.admin.api.entity.SysLog; import com.pig4cloud.pig.common.core.constant.CommonConstants; -import com.pig4cloud.pig.common.core.constant.SecurityConstants; -import com.pig4cloud.pig.common.core.util.MsgUtils; import com.pig4cloud.pig.common.core.util.R; import com.pig4cloud.pig.common.core.util.SpringContextHolder; import com.pig4cloud.pig.common.log.event.SysLogEvent; @@ -97,12 +95,6 @@ private void sendErrorResponse(HttpServletRequest request, HttpServletResponse r errorMessage = exception.getLocalizedMessage(); } - // 手机号登录 - String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); - if (SecurityConstants.MOBILE.equals(grantType)) { - errorMessage = MsgUtils.getSecurityMessage("AbstractUserDetailsAuthenticationProvider.smsBadCredentials"); - } - this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse); } diff --git a/pig-boot/Dockerfile b/pig-boot/Dockerfile new file mode 100755 index 000000000..a4a08e678 --- /dev/null +++ b/pig-boot/Dockerfile @@ -0,0 +1,13 @@ +FROM alibabadragonwell/dragonwell:21-anolis + +WORKDIR /pig-boot + +ARG JAR_FILE=target/pig-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/pig-boot/pom.xml b/pig-boot/pom.xml new file mode 100755 index 000000000..1ccbebd92 --- /dev/null +++ b/pig-boot/pom.xml @@ -0,0 +1,114 @@ + + + + + 4.0.0 + + com.pig4cloud + pig + ${revision} + + + pig-boot + jar + + pig 单体版本启动 + + + + + com.pig4cloud + pig-auth + ${revision} + + + org.springframework.boot + spring-boot-maven-plugin + + + + + com.pig4cloud + pig-codegen + ${revision} + + + + com.pig4cloud + pig-quartz + ${revision} + + + + com.pig4cloud + pig-upms-biz + ${revision} + + + + com.pig4cloud + pig-common-security + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + + com.pig4cloud + pig-common-swagger + + + + org.springframework.boot + spring-boot-starter-undertow + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + io.fabric8 + docker-maven-plugin + + + + + + + boot + + + dev + + + + true + + + + diff --git a/pig-boot/src/main/java/com/pig4cloud/pig/PigBootApplication.java b/pig-boot/src/main/java/com/pig4cloud/pig/PigBootApplication.java new file mode 100755 index 000000000..a8955e3d1 --- /dev/null +++ b/pig-boot/src/main/java/com/pig4cloud/pig/PigBootApplication.java @@ -0,0 +1,37 @@ +/* + * 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.pig; + +import com.pig4cloud.pig.common.security.annotation.EnablePigResourceServer; +import com.pig4cloud.pig.common.swagger.annotation.EnablePigDoc; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author lengleng + * 单体版本启动器,只需要运行此模块则整个系统启动 + */ +@EnablePigDoc(value = "admin", isMicro = false) +@EnablePigResourceServer +@SpringBootApplication +public class PigBootApplication { + + public static void main(String[] args) { + SpringApplication.run(PigBootApplication.class, args); + } + +} diff --git a/pig-boot/src/main/java/com/pig4cloud/pig/bootstrap/PigBootSecurityServerConfiguration.java b/pig-boot/src/main/java/com/pig4cloud/pig/bootstrap/PigBootSecurityServerConfiguration.java new file mode 100644 index 000000000..8984c9067 --- /dev/null +++ b/pig-boot/src/main/java/com/pig4cloud/pig/bootstrap/PigBootSecurityServerConfiguration.java @@ -0,0 +1,161 @@ +/* + * + * 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.pig.bootstrap; + +import com.pig4cloud.pig.auth.support.core.PigDaoAuthenticationProvider; +import com.pig4cloud.pig.auth.support.filter.PasswordDecoderFilter; +import com.pig4cloud.pig.auth.support.filter.ValidateCodeFilter; +import com.pig4cloud.pig.auth.support.handler.PigAuthenticationFailureEventHandler; +import com.pig4cloud.pig.auth.support.handler.PigAuthenticationSuccessEventHandler; +import com.pig4cloud.pig.auth.support.password.OAuth2ResourceOwnerPasswordAuthenticationProvider; +import com.pig4cloud.pig.auth.support.sms.OAuth2ResourceOwnerSmsAuthenticationProvider; +import com.pig4cloud.pig.common.core.constant.SecurityConstants; +import com.pig4cloud.pig.common.security.component.PermitAllUrlProperties; +import com.pig4cloud.pig.common.security.component.PigBearerTokenExtractor; +import com.pig4cloud.pig.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 PigBootSecurityServerConfiguration { + + private final ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint; + + private final OpaqueTokenIntrospector customOpaqueTokenIntrospector; + + private final AuthenticationConverter accessTokenRequestConverter; + + private final OAuth2AuthorizationService authorizationService; + + private final PigBearerTokenExtractor 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) 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(new PigAuthenticationSuccessEventHandler()) // 登录成功处理器 + .errorResponseHandler(new PigAuthenticationFailureEventHandler());// 登录失败处理器 + }).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证 + oAuth2ClientAuthenticationConfigurer.errorResponseHandler(new PigAuthenticationFailureEventHandler()))// 处理客户端认证异常 + , Customizer.withDefaults()) + .with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现 + .authorizationServerSettings( + AuthorizationServerSettings.builder().issuer(SecurityConstants.PROJECT_LICENSE).build()), + Customizer.withDefaults()); + + // 资源服务器配置 + AntPathRequestMatcher[] requestMatchers = permitAllUrl.getUrls() + .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.PROJECT_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 PigDaoAuthenticationProvider()); + // 处理 OAuth2ResourceOwnerPasswordAuthenticationToken + http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider); + // 处理 OAuth2ResourceOwnerSmsAuthenticationToken + http.authenticationProvider(resourceOwnerSmsAuthenticationProvider); + } + +} diff --git a/pig-boot/src/main/resources/application-dev.yml b/pig-boot/src/main/resources/application-dev.yml new file mode 100644 index 000000000..6f7008eba --- /dev/null +++ b/pig-boot/src/main/resources/application-dev.yml @@ -0,0 +1,31 @@ +spring: + data: + redis: + host: pig-redis + # 数据库相关配置 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: root + url: jdbc:mysql://pig-mysql:3306/pig?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 + +## 登录配置 +security: + # 登录报文加密根密钥 ,必须是16位 + encodeKey: thanks,pig4cloud + # 跳过验证码校验的客户端 + ignore-clients: + - test + +# 配置文件加密根密码 +jasypt: + encryptor: + password: pig + algorithm: PBEWithMD5AndDES + iv-generator-classname: org.jasypt.iv.NoIvGenerator diff --git a/pig-boot/src/main/resources/application.yml b/pig-boot/src/main/resources/application.yml new file mode 100644 index 000000000..d5c371989 --- /dev/null +++ b/pig-boot/src/main/resources/application.yml @@ -0,0 +1,86 @@ +server: + port: 9999 + servlet: + context-path: /admin + +spring: + application: + name: @project.artifactId@ + # 缓存相关配置 + cache: + type: redis + # 定时任务属性配置 + quartz: + properties: + org: + quartz: + scheduler: + instanceName: clusteredScheduler + instanceId: AUTO + jobStore: + class: org.springframework.scheduling.quartz.LocalDataSourceJobStore + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: true + clusterCheckinInterval: 10000 + useProperties: false + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 50 + threadPriority: 5 + threadsInheritContextClassLoaderOfInitializingThread: true + job-store-type: jdbc + jdbc: + initialize-schema: always # 生产注意设置为 never + startup-delay: 10 + # 上传文件大小限制 + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + cloud: + nacos: + config: + enabled: false + discovery: + enabled: false + main: + allow-bean-definition-overriding: true + profiles: + active: dev + + +## spring security 对外暴露接口设置 +security: + micro: false + oauth2: + ignore: + urls: + - /webjars/** + - /v3/api-docs/** + - /doc.html + - /swagger-ui.html + - /swagger-ui/** + - /swagger-resources + - /token/check_token + - /error + - /token/** + - /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.pig.common.mybatis.handler + configuration: + jdbc-type-for-null: 'null' + call-setters-on-nulls: true + shrink-whitespaces-in-sql: true diff --git a/pig-upms/pig-upms-biz/src/main/java/com/pig4cloud/pig/admin/PigAdminApplication.java b/pig-upms/pig-upms-biz/src/main/java/com/pig4cloud/pig/admin/PigAdminApplication.java index 13a1eca28..4847cc08f 100644 --- a/pig-upms/pig-upms-biz/src/main/java/com/pig4cloud/pig/admin/PigAdminApplication.java +++ b/pig-upms/pig-upms-biz/src/main/java/com/pig4cloud/pig/admin/PigAdminApplication.java @@ -19,6 +19,7 @@ package com.pig4cloud.pig.admin; +import com.pig4cloud.pig.common.feign.annotation.EnablePigFeignClients; import com.pig4cloud.pig.common.security.annotation.EnablePigResourceServer; import com.pig4cloud.pig.common.swagger.annotation.EnablePigDoc; import org.springframework.boot.SpringApplication; @@ -32,6 +33,7 @@ * 用户统一管理系统 */ @EnablePigDoc(value = "admin") +@EnablePigFeignClients @EnablePigResourceServer @EnableDiscoveryClient @SpringBootApplication