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
+ * 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