diff --git a/gradle.properties b/gradle.properties index 50df8a37..fb0ddac7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,8 +14,8 @@ # * limitations under the License. # */ #maxkey properties -group =net.maxsso -version =3.5.17 +group =org.dromara.maxkey +version =3.5.18 vendor =https://www.maxkey.top author =MaxKeyTop @@ -28,7 +28,7 @@ jibToAuthPassword =docker registry credential #maxkey used jars version #spring springVersion =5.3.27 -springBootVersion =2.7.11 +springBootVersion =2.7.12 springSecurityVersion =5.7.8 springDataVersion =2.7.8 springkafkaVersion =2.9.0 @@ -74,7 +74,7 @@ kafkaclientsVersion =2.8.9 rocketmqclientVersion =4.9.4 rocketmqspringbootVersion =2.2.2 #apache tomcat -tomcatVersion =9.0.74 +tomcatVersion =9.0.75 tomcatembedloggingjuliVersion =8.5.2 #logs log4jVersion =2.19.0 diff --git a/maxkey-webs/maxkey-gataway/src/main/resources/application.yml b/maxkey-webs/maxkey-gataway/src/main/resources/application.yml index 8250dec1..730d54de 100644 --- a/maxkey-webs/maxkey-gataway/src/main/resources/application.yml +++ b/maxkey-webs/maxkey-gataway/src/main/resources/application.yml @@ -1,7 +1,7 @@ #端口号 application: name: maxkey-gateway-server - formatted-version: v3.5.17 GA + formatted-version: v3.5.18 GA server: port: 9000 spring: diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/application.properties b/maxkey-webs/maxkey-web-maxkey/src/main/resources/application.properties index 998f1aa7..0167c65a 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/resources/application.properties +++ b/maxkey-webs/maxkey-web-maxkey/src/main/resources/application.properties @@ -16,7 +16,7 @@ #MaxKey Title and Version # ############################################################################ application.title =MaxKey -application.formatted-version =v3.5.17 GA +application.formatted-version =v3.5.18 GA #for dynamic service discovery spring.application.name =maxkey ############################################################################ diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/application.properties b/maxkey-webs/maxkey-web-mgt/src/main/resources/application.properties index 20114fd2..75c5b986 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/application.properties +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/application.properties @@ -16,7 +16,7 @@ #MaxKey Title and Version # ############################################################################ application.title =MaxKey-Mgt -application.formatted-version =v3.5.17 GA +application.formatted-version =v3.5.18 GA #for dynamic service discovery spring.application.name =maxkey-mgt ############################################################################ diff --git a/maxkey-webs/maxkey-web-openapi/build.gradle b/maxkey-webs/maxkey-web-openapi/build.gradle new file mode 100644 index 00000000..328ec089 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/build.gradle @@ -0,0 +1,24 @@ +description = "maxkey-web-openapi" + +//add support for Java +apply plugin: 'java' + +dependencies { + implementation project(":maxkey-common") + implementation project(":maxkey-core") + implementation project(":maxkey-persistence") + + implementation project(":maxkey-authentications:maxkey-authentication-core") + implementation project(":maxkey-authentications:maxkey-authentication-captcha") + implementation project(":maxkey-authentications:maxkey-authentication-otp") + implementation project(":maxkey-authentications:maxkey-authentication-provider") + implementation project(":maxkey-authentications:maxkey-authentication-sms") + + implementation project(":maxkey-protocols:maxkey-protocol-oauth-2.0") + implementation project(":maxkey-protocols:maxkey-protocol-saml-2.0") + + //rest apis + implementation project(":maxkey-web-apis:maxkey-web-api-scim") + implementation project(":maxkey-web-apis:maxkey-web-api-rest") + +} \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/config/build_docker.gradle b/maxkey-webs/maxkey-web-openapi/config/build_docker.gradle new file mode 100644 index 00000000..d0291cc9 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/config/build_docker.gradle @@ -0,0 +1,59 @@ +buildscript { + repositories { + maven { url 'https://maven.aliyun.com/nexus/content/groups/public/'} + } +} +//docker +plugins { + id 'java' + id 'com.google.cloud.tools.jib' version "${jibGradlePluginVersion}" + id 'org.springframework.boot' version "${springBootVersion}" +} + + +apply plugin: 'com.google.cloud.tools.jib' + +description = "maxkey-web-openapi" + +jib { + from { + image = "${jibFromImage}" + } + to { + //https://registry.hub.docker.com/repository/docker/maxkeytop/maxkey-openapi + image = "${jibToImage}/maxkey-openapi" + tags = ["${project.version}".toString(), 'latest'] + auth { + username = "${jibToAuthUsername}" + password = "${jibToAuthPassword}" + } + + } + container { + mainClass = "org.maxkey.MaxKeyOpenApiApplication" + jvmFlags = ['-Dfile.encoding=utf-8', '-Dserver.port=9526','-Duser.timezone=Asia/Shanghai'] + ports = ['9525'] + } +} + +//build.configure { finalizedBy jib } + +dependencies { + implementation project(":maxkey-common") + implementation project(":maxkey-core") + implementation project(":maxkey-persistence") + + implementation project(":maxkey-authentications:maxkey-authentication-core") + implementation project(":maxkey-authentications:maxkey-authentication-captcha") + implementation project(":maxkey-authentications:maxkey-authentication-otp") + implementation project(":maxkey-authentications:maxkey-authentication-provider") + implementation project(":maxkey-authentications:maxkey-authentication-sms") + + implementation project(":maxkey-protocols:maxkey-protocol-oauth-2.0") + implementation project(":maxkey-protocols:maxkey-protocol-saml-2.0") + + //webapis + implementation project(":maxkey-web-apis:maxkey-web-api-scim") + implementation project(":maxkey-web-apis:maxkey-web-api-rest") + +} \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/config/build_jar.gradle b/maxkey-webs/maxkey-web-openapi/config/build_jar.gradle new file mode 100644 index 00000000..c610362f --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/config/build_jar.gradle @@ -0,0 +1,59 @@ +buildscript { + repositories { + maven { url 'https://maven.aliyun.com/nexus/content/groups/public/'} + } + dependencies { + //springboot jar + classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") + } +} + +plugins { + id 'org.springframework.boot' version "${springBootVersion}" + id "io.spring.dependency-management" version "1.0.11.RELEASE" +} + +description = "maxkey-web-openapi" + +//springboot jar +apply plugin: 'io.spring.dependency-management' + +//add support for Java +apply plugin: 'java' + + + +bootJar { + dependsOn jar + baseName = 'maxkey-openapi-boot' + version = "${project.version}-ga" + mainClass = 'org.maxkey.MaxKeyOpenApiApplication' + manifest { + attributes( + "Implementation-Title": project.name, + "Implementation-Vendor": project.vendor, + "Created-By": project.author, + "Implementation-Date": java.time.ZonedDateTime.now(), + "Implementation-Version": project.version + ) + } +} + +dependencies { + implementation project(":maxkey-common") + implementation project(":maxkey-core") + implementation project(":maxkey-persistence") + + implementation project(":maxkey-authentications:maxkey-authentication-core") + implementation project(":maxkey-authentications:maxkey-authentication-captcha") + implementation project(":maxkey-authentications:maxkey-authentication-otp") + implementation project(":maxkey-authentications:maxkey-authentication-provider") + implementation project(":maxkey-authentications:maxkey-authentication-sms") + + implementation project(":maxkey-protocols:maxkey-protocol-oauth-2.0") + implementation project(":maxkey-protocols:maxkey-protocol-saml-2.0") + + //webapis + implementation project(":maxkey-web-apis:maxkey-web-api-scim") + implementation project(":maxkey-web-apis:maxkey-web-api-rest") +} diff --git a/maxkey-webs/maxkey-web-openapi/config/build_standard.gradle b/maxkey-webs/maxkey-web-openapi/config/build_standard.gradle new file mode 100644 index 00000000..0ea487f2 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/config/build_standard.gradle @@ -0,0 +1,24 @@ +description = "maxkey-web-openapi" + +//add support for Java +apply plugin: 'java' + +dependencies { + implementation project(":maxkey-common") + implementation project(":maxkey-core") + implementation project(":maxkey-persistence") + + implementation project(":maxkey-authentications:maxkey-authentication-core") + implementation project(":maxkey-authentications:maxkey-authentication-captcha") + implementation project(":maxkey-authentications:maxkey-authentication-otp") + implementation project(":maxkey-authentications:maxkey-authentication-provider") + implementation project(":maxkey-authentications:maxkey-authentication-sms") + + implementation project(":maxkey-protocols:maxkey-protocol-oauth-2.0") + implementation project(":maxkey-protocols:maxkey-protocol-saml-2.0") + + //webapis + implementation project(":maxkey-web-apis:maxkey-web-api-scim") + implementation project(":maxkey-web-apis:maxkey-web-api-rest") + +} \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/META-INF/MANIFEST.MF b/maxkey-webs/maxkey-web-openapi/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 00000000..59499bce --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/MaxKeyOpenApiApplication.java b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/MaxKeyOpenApiApplication.java new file mode 100644 index 00000000..213246f4 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/MaxKeyOpenApiApplication.java @@ -0,0 +1,82 @@ +/* + * Copyright [2020] [MaxKey of copyright http://www.maxkey.top] + * + * 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 org.maxkey; + +import javax.servlet.ServletException; + +import org.joda.time.DateTime; +import org.maxkey.configuration.ApplicationConfig; +import org.maxkey.web.InitializeContext; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan(basePackages = { + "org.maxkey.authn", + "org.maxkey.configuration", + "org.maxkey.entity", + "org.maxkey.entity.apps", + "org.maxkey.entity.userinfo", + "org.maxkey.web.apis.identity.kafka", + "org.maxkey.web.apis.identity.rest", + "org.maxkey.web.apis.identity.scim", + "org.maxkey.persistence", + "org.maxkey.provision", + "org.maxkey.web", + "org.maxkey.web.api.endpoint", + "org.maxkey.web.contorller", + "org.maxkey.web.endpoint", + "org.maxkey.web.interceptor", +}) +@MapperScan("org.maxkey.persistence.mapper,") +@SpringBootApplication +@EnableDiscoveryClient +public class MaxKeyOpenApiApplication extends SpringBootServletInitializer { + private static final Logger _logger = LoggerFactory.getLogger(MaxKeyOpenApiApplication.class); + + public static void main(String[] args) { + _logger.info("Start MaxKey OpenApi Application ..."); + + ConfigurableApplicationContext applicationContext = + SpringApplication.run(MaxKeyOpenApiApplication.class, args); + InitializeContext initWebContext = new InitializeContext(applicationContext); + + try { + initWebContext.init(null); + } catch (ServletException e) { + _logger.error("Exception ",e); + } + _logger.info("MaxKey OpenApi at {}" , new DateTime()); + _logger.info("MaxKey OpenApi Server Port {}" + ,applicationContext.getBean(ApplicationConfig.class).getPort()); + _logger.info("MaxKey OpenApi started."); + + } + + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(MaxKeyOpenApiApplication.class); + } + +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiConfig.java b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiConfig.java new file mode 100644 index 00000000..2f21d9fd --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiConfig.java @@ -0,0 +1,73 @@ +/* + * Copyright [2022] [MaxKey of copyright http://www.maxkey.top] + * + * 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 org.maxkey.autoconfigure; + +import org.maxkey.password.onetimepwd.AbstractOtpAuthn; +import org.maxkey.password.onetimepwd.impl.TimeBasedOtpAuthn; +import org.maxkey.persistence.repository.LoginHistoryRepository; +import org.maxkey.persistence.repository.LoginRepository; +import org.maxkey.persistence.repository.PasswordPolicyValidator; +import org.maxkey.persistence.service.UserInfoService; +import org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.crypto.password.PasswordEncoder; + +@AutoConfiguration +public class MaxKeyOpenApiConfig implements InitializingBean { + private static final Logger _logger = LoggerFactory.getLogger(MaxKeyOpenApiConfig.class); + + //authenticationRealm for MaxKeyMgtApplication + @Bean + public JdbcAuthenticationRealm authenticationRealm( + PasswordEncoder passwordEncoder, + PasswordPolicyValidator passwordPolicyValidator, + LoginRepository loginRepository, + LoginHistoryRepository loginHistoryRepository, + UserInfoService userInfoService, + JdbcTemplate jdbcTemplate) { + + JdbcAuthenticationRealm authenticationRealm = new JdbcAuthenticationRealm( + passwordEncoder, + passwordPolicyValidator, + loginRepository, + loginHistoryRepository, + userInfoService, + jdbcTemplate); + + _logger.debug("JdbcAuthenticationRealm inited."); + return authenticationRealm; + } + + @Bean + public AbstractOtpAuthn timeBasedOtpAuthn() { + AbstractOtpAuthn tfaOtpAuthn = new TimeBasedOtpAuthn(); + _logger.debug("TimeBasedOtpAuthn inited."); + return tfaOtpAuthn; + } + + @Override + public void afterPropertiesSet() throws Exception { + + } + +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiMvcConfig.java b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiMvcConfig.java new file mode 100644 index 00000000..4277c083 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiMvcConfig.java @@ -0,0 +1,144 @@ +/* + * Copyright [2022] [MaxKey of copyright http://www.maxkey.top] + * + * 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 org.maxkey.autoconfigure; + +import java.util.List; + +import org.maxkey.authn.provider.AbstractAuthenticationProvider; +import org.maxkey.authn.web.CurrentUserMethodArgumentResolver; +import org.maxkey.authn.web.interceptor.PermissionInterceptor; +import org.maxkey.configuration.ApplicationConfig; +import org.maxkey.web.interceptor.RestApiPermissionAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; + +@EnableWebMvc +@AutoConfiguration +public class MaxKeyOpenApiMvcConfig implements WebMvcConfigurer { + private static final Logger _logger = LoggerFactory.getLogger(MaxKeyOpenApiMvcConfig.class); + + @Autowired + ApplicationConfig applicationConfig; + + @Autowired + AbstractAuthenticationProvider authenticationProvider ; + + @Autowired + PermissionInterceptor permissionInterceptor; + + @Autowired + RestApiPermissionAdapter restApiPermissionAdapter; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + _logger.debug("add Resource Handlers"); + + _logger.debug("add statics"); + registry.addResourceHandler("/static/**") + .addResourceLocations("classpath:/static/"); + _logger.debug("add templates"); + registry.addResourceHandler("/templates/**") + .addResourceLocations("classpath:/templates/"); + + _logger.debug("add swagger"); + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + + _logger.debug("add knife4j"); + registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + + _logger.debug("add Resource Handler finished ."); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + //addPathPatterns 用于添加拦截规则 , 先把所有路径都加入拦截, 再一个个排除 + //excludePathPatterns 表示改路径不用拦截 + _logger.debug("add Interceptors"); + + permissionInterceptor.setMgmt(true); + + registry.addInterceptor(permissionInterceptor) + .addPathPatterns("/dashboard/**") + .addPathPatterns("/orgs/**") + .addPathPatterns("/users/**") + .addPathPatterns("/apps/**") + .addPathPatterns("/session/**") + .addPathPatterns("/accounts/**") + + + .addPathPatterns("/access/**") + .addPathPatterns("/access/**/**") + + .addPathPatterns("/permissions/**") + .addPathPatterns("/permissions/**/**") + + .addPathPatterns("/config/**") + .addPathPatterns("/config/**/**") + + .addPathPatterns("/historys/**") + .addPathPatterns("/historys/**/**") + + .addPathPatterns("/institutions/**") + .addPathPatterns("/localization/**") + + .addPathPatterns("/file/upload/") + + .addPathPatterns("/logout") + .addPathPatterns("/logout/**") + ; + + _logger.debug("add Permission Adapter"); + + /* + * api + * idm + * scim + * */ + registry.addInterceptor(restApiPermissionAdapter) + .addPathPatterns("/api/**") + .addPathPatterns("/api/idm/**") + .addPathPatterns("/api/idm/scim/**") + ; + + _logger.debug("add Rest Api Permission Adapter"); + + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(currentUserMethodArgumentResolver()); + } + + @Bean + public CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() { + return new CurrentUserMethodArgumentResolver(); + } + +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/Oauth20ClientAutoConfiguration.java b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/Oauth20ClientAutoConfiguration.java new file mode 100644 index 00000000..fb1ccaf9 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/Oauth20ClientAutoConfiguration.java @@ -0,0 +1,121 @@ +/* + * Copyright [2020] [MaxKey of copyright http://www.maxkey.top] + * + * 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 org.maxkey.autoconfigure; + +import javax.sql.DataSource; + +import org.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService; +import org.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService; +import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices; +import org.maxkey.authz.oauth2.provider.token.TokenStore; +import org.maxkey.authz.oauth2.provider.token.store.InMemoryTokenStore; +import org.maxkey.authz.oauth2.provider.token.store.RedisTokenStore; +import org.maxkey.persistence.redis.RedisConnectionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.crypto.password.PasswordEncoder; + +/** + * like Oauth20AutoConfiguration for mgmt + * @author Crystal.Sea + * + */ +@AutoConfiguration +public class Oauth20ClientAutoConfiguration implements InitializingBean { + private static final Logger _logger = LoggerFactory.getLogger(Oauth20ClientAutoConfiguration.class); + + @Bean + public JdbcClientDetailsService oauth20JdbcClientDetailsService( + DataSource dataSource,PasswordEncoder passwordReciprocal) { + JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource); + //clientDetailsService.setPasswordEncoder(passwordReciprocal); + _logger.debug("JdbcClientDetailsService inited."); + return clientDetailsService; + } + + /** + * TokenStore. + * @param persistence int + * @return oauth20TokenStore + */ + @Bean + public TokenStore oauth20TokenStore( + @Value("${maxkey.server.persistence}") int persistence, + JdbcTemplate jdbcTemplate, + RedisConnectionFactory jedisConnectionFactory) { + TokenStore tokenStore = null; + if (persistence == 2) { + tokenStore = new RedisTokenStore(jedisConnectionFactory); + _logger.debug("RedisTokenStore"); + }else { + tokenStore = new InMemoryTokenStore(); + _logger.debug("InMemoryTokenStore"); + } + + return tokenStore; + } + + /** + * clientDetailsUserDetailsService. + * @return oauth20TokenServices + */ + @Bean + public DefaultTokenServices oauth20TokenServices( + JdbcClientDetailsService oauth20JdbcClientDetailsService, + TokenStore oauth20TokenStore) { + DefaultTokenServices tokenServices = new DefaultTokenServices(); + tokenServices.setClientDetailsService(oauth20JdbcClientDetailsService); + tokenServices.setTokenStore(oauth20TokenStore); + tokenServices.setSupportRefreshToken(true); + return tokenServices; + } + + /** + * ProviderManager. + * @return oauth20ClientAuthenticationManager + */ + @Bean + public ProviderManager oauth20ClientAuthenticationManager( + JdbcClientDetailsService oauth20JdbcClientDetailsService, + PasswordEncoder passwordReciprocal + ) { + + ClientDetailsUserDetailsService cientDetailsUserDetailsService = + new ClientDetailsUserDetailsService(oauth20JdbcClientDetailsService); + + DaoAuthenticationProvider daoAuthenticationProvider= new DaoAuthenticationProvider(); + daoAuthenticationProvider.setPasswordEncoder(passwordReciprocal); + daoAuthenticationProvider.setUserDetailsService(cientDetailsUserDetailsService); + ProviderManager authenticationManager = new ProviderManager(daoAuthenticationProvider); + _logger.debug("OAuth 2 Client Authentication Manager init."); + return authenticationManager; + } + + @Override + public void afterPropertiesSet() throws Exception { + + } + +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/api/endpoint/RestTimeBasedOtpController.java b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/api/endpoint/RestTimeBasedOtpController.java new file mode 100644 index 00000000..8c7a1501 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/api/endpoint/RestTimeBasedOtpController.java @@ -0,0 +1,60 @@ +/* + * Copyright [2020] [MaxKey of copyright http://www.maxkey.top] + * + * 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 org.maxkey.web.api.endpoint; + +import org.maxkey.entity.UserInfo; +import org.maxkey.password.onetimepwd.AbstractOtpAuthn; +import org.maxkey.persistence.service.UserInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "基于时间令牌验证 API文档模块") +@Controller +@RequestMapping(value={"/api/otp"}) +public class RestTimeBasedOtpController { + + @Autowired + protected AbstractOtpAuthn timeBasedOtpAuthn; + + @Autowired + private UserInfoService userInfoService; + + @Operation(summary = "基于时间令牌验证 API文档模块", description = "传递参数username和token",method="GET") + @ResponseBody + @RequestMapping(value = "/timebased/validate", method = RequestMethod.GET) + public boolean getUser(@RequestParam String username, + @RequestParam String token) { + + UserInfo validUserInfo = userInfoService.findByUsername(username); + if(validUserInfo != null) { + if(timeBasedOtpAuthn.validate(validUserInfo, token)) { + return true; + } + } + + return false; + } + + +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java new file mode 100644 index 00000000..d68d700c --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java @@ -0,0 +1,80 @@ +/* + * Copyright [2020] [MaxKey of copyright http://www.maxkey.top] + * + * 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 org.maxkey.web.interceptor; + +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.maxkey.authz.oauth2.provider.OAuth2Authentication; +import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices; +import org.maxkey.crypto.password.PasswordReciprocal; +import org.maxkey.util.RequestTokenUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.AsyncHandlerInterceptor; + +/** + * OAuth v2.0 accessToken认证Interceptor处理. + * @author Crystal.Sea + * + */ +@Component +public class Oauth20ApiPermissionAdapter implements AsyncHandlerInterceptor { + private static final Logger _logger = LoggerFactory.getLogger(Oauth20ApiPermissionAdapter.class); + + @Autowired + protected PasswordReciprocal passwordReciprocal; + + @Autowired + private DefaultTokenServices oauth20TokenServices; + + static ConcurrentHashMapnavigationsMap=null; + + /* + * 请求前处理 + * (non-Javadoc) + * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object) + */ + @Override + public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception { + _logger.trace("OAuth20 API Permission Adapter pre handle"); + String accessToken = RequestTokenUtils.resolveAccessToken(request); + _logger.trace("access_token {} " , accessToken); + try { + OAuth2Authentication authentication = oauth20TokenServices.loadAuthentication(accessToken); + //判断应用的accessToken信息 + if(authentication != null ){ + _logger.trace("authentication "+ authentication); + return true; + } + }catch(Exception e) { + _logger.error("load Authentication Exception ! ",e); + } + + _logger.trace("No Authentication ... forward to /login"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/login"); + dispatcher.forward(request, response); + + return false; + } +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java new file mode 100644 index 00000000..68a52c89 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java @@ -0,0 +1,112 @@ +/* + * Copyright [2020] [MaxKey of copyright http://www.maxkey.top] + * + * 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 org.maxkey.web.interceptor; + +import java.util.concurrent.ConcurrentHashMap; +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.maxkey.authn.web.AuthorizationUtils; +import org.maxkey.authz.oauth2.provider.OAuth2Authentication; +import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices; +import org.maxkey.util.AuthorizationHeader; +import org.maxkey.util.AuthorizationHeaderUtils; +import org.maxkey.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.AsyncHandlerInterceptor; + +/** + * basic认证Interceptor处理. + * @author Crystal.Sea + * + */ +@Component +public class RestApiPermissionAdapter implements AsyncHandlerInterceptor { + private static final Logger _logger = LoggerFactory.getLogger(RestApiPermissionAdapter.class); + + @Autowired + DefaultTokenServices oauth20TokenServices; + + @Autowired + ProviderManager oauth20ClientAuthenticationManager; + + static ConcurrentHashMapnavigationsMap=null; + + /* + * 请求前处理 + * (non-Javadoc) + * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object) + */ + @Override + public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception { + _logger.trace("Rest API Permission Adapter pre handle"); + AuthorizationHeader headerCredential = AuthorizationHeaderUtils.resolve(request); + + //判断应用的AppId和Secret + if(headerCredential != null){ + UsernamePasswordAuthenticationToken authenticationToken = null; + if(headerCredential.isBasic()) { + if(StringUtils.isNotBlank(headerCredential.getUsername())&& + StringUtils.isNotBlank(headerCredential.getCredential()) + ) { + UsernamePasswordAuthenticationToken authRequest = + new UsernamePasswordAuthenticationToken( + headerCredential.getUsername(), + headerCredential.getCredential()); + authenticationToken= (UsernamePasswordAuthenticationToken)oauth20ClientAuthenticationManager.authenticate(authRequest); + } + }else { + _logger.trace("Authentication bearer {}" , headerCredential.getCredential()); + OAuth2Authentication oauth2Authentication = + oauth20TokenServices.loadAuthentication(headerCredential.getCredential()); + + if(oauth2Authentication != null) { + _logger.trace("Authentication token {}" , oauth2Authentication.getPrincipal().toString()); + authenticationToken= new UsernamePasswordAuthenticationToken( + new User( + oauth2Authentication.getPrincipal().toString(), + "CLIENT_SECRET", + oauth2Authentication.getAuthorities()), + "PASSWORD", + oauth2Authentication.getAuthorities() + ); + }else { + _logger.trace("Authentication token is null "); + } + } + + if(authenticationToken !=null && authenticationToken.isAuthenticated()) { + AuthorizationUtils.setAuthentication(authenticationToken); + return true; + } + } + + _logger.trace("No Authentication ... forward to /login"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/login"); + dispatcher.forward(request, response); + + return false; + } +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/maxkey-webs/maxkey-web-openapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..c10d3733 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,14 @@ +org.maxkey.autoconfigure.ApplicationAutoConfiguration +org.maxkey.autoconfigure.KaptchaAutoConfiguration +org.maxkey.autoconfigure.MvcAutoConfiguration +org.maxkey.autoconfigure.JwtAuthnAutoConfiguration +org.maxkey.autoconfigure.RedisAutoConfiguration +org.maxkey.autoconfigure.AuthnProviderAutoConfiguration +org.maxkey.autoconfigure.OneTimePasswordAutoConfiguration +org.maxkey.autoconfigure.SmsAutoConfiguration +org.maxkey.autoconfigure.SessionAutoConfiguration +org.maxkey.autoconfigure.TokenAutoConfiguration +org.maxkey.autoconfigure.SwaggerConfig +org.maxkey.autoconfigure.Oauth20ClientAutoConfiguration +org.maxkey.autoconfigure.MaxKeyOpenApiConfig +org.maxkey.autoconfigure.MaxKeyOpenApiMvcConfig \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties b/maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties new file mode 100644 index 00000000..46474dbc --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties @@ -0,0 +1,258 @@ +############################################################################ +# Copyright [2022] [MaxKey of copyright http://www.maxkey.top] +# +# 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. +############################################################################ +#MaxKey Server configuration # +############################################################################ +#server port +server.port =${SERVER_PORT:9525} +#server context path +server.servlet.context-path =/open +############################################################################ +#domain name configuration # +############################################################################ +maxkey.server.scheme =http +maxkey.server.basedomain =${SERVER_DOMAIN:maxkey.top} +maxkey.server.domain =sso.${maxkey.server.basedomain} +maxkey.server.name =${maxkey.server.scheme}://${maxkey.server.domain} +maxkey.server.uri =${maxkey.server.name}:${server.port}${server.servlet.context-path} +#default.uri +maxkey.server.default.uri =${maxkey.server.uri}/main +maxkey.server.mgt.uri =${maxkey.server.uri} +maxkey.server.authz.uri =https://${maxkey.server.domain}/maxkey +#InMemory 0 , Redis 2 +maxkey.server.persistence =${SERVER_PERSISTENCE:0} +#identity true,false +maxkey.server.provision =${SERVER_PROVISION:false} + +maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800} + +maxkey.auth.jwt.issuer =${maxkey.server.uri} +#default 900 +maxkey.auth.jwt.expires =900 +maxkey.auth.jwt.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg +maxkey.auth.jwt.refresh.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg +#plain,bcrypt,pbkdf2,scrypt,md4,md5,sha1,sha256,sha384,sha512,sm3,ldap +maxkey.crypto.password.encoder =bcrypt +############################################################################ +#Login configuration # +############################################################################ +#enable captcha +maxkey.login.captcha =${LOGIN_CAPTCHA:true} +#enable two factor,use one time password +maxkey.login.mfa =false +#Enable kerberos/SPNEGO +maxkey.login.kerberos =false +#wsFederation +maxkey.login.wsfederation =false +#remeberme +maxkey.login.remeberme =false +#validity +maxkey.login.remeberme.validity =0 +#ipaddress whitelist +maxkey.ipaddress.whitelist =false +#JWT support +maxkey.login.jwt =${LOGIN_JWT:true} +maxkey.login.jwt.issuer =${LOGIN_JWT_ISSUER:${maxkey.server.authz.uri}} + +############################################################################ +#database configuration +# supported database +# mysql +# highgo +# postgresql +############################################################################ +spring.datasource.type =com.alibaba.druid.pool.DruidDataSource +#mysql +spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver +spring.datasource.username =${DATABASE_USER:root} +spring.datasource.password =${DATABASE_PWD:maxkey} +spring.datasource.url =jdbc:mysql://${DATABASE_HOST:localhost}:${DATABASE_PORT:3306}/${DATABASE_NAME:maxkey}?autoReconnect=true&characterEncoding=UTF-8&serverTimezone=UTC +#highgo +#spring.datasource.driver-class-name=com.highgo.jdbc.Driver +#spring.datasource.username=highgo +#spring.datasource.password=High@123 +#spring.datasource.url=jdbc:highgo://192.168.56.107:5866/highgo?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai +#postgresql +#spring.datasource.driver-class-name=org.postgresql.Driver +#spring.datasource.username=root +#spring.datasource.password=maxkey! +#spring.datasource.url=jdbc:postgresql://localhost/maxkey?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai +#mybatis +mybatis.dialect =mysql +mybatis.type-aliases-package =org.maxkey.entity,org.maxkey.entity.apps, +mybatis.mapper-locations =classpath*:/org/maxkey/persistence/mapper/xml/${mybatis.dialect}/*.xml +mybatis.table-column-snowflake-datacenter-id =1 +mybatis.table-column-snowflake-machine-id =1 +mybatis.table-column-escape =false +mybatis.table-column-case =lowercase + +############################################################################ +#redis server configuration # +############################################################################ +spring.redis.host =${REDIS_HOST:127.0.0.1} +spring.redis.port =${REDIS_PORT:6379} +spring.redis.password =${REDIS_PWD:password} +spring.redis.timeout =10000 +spring.redis.jedis.pool.max-wait =1000 +spring.redis.jedis.pool.max-idle =200 +spring.redis.lettuce.pool.max-active =-1 +spring.redis.lettuce.pool.min-idle =0 + +############################################################################ +#mail configuration # +############################################################################ +spring.mail.default-encoding =utf-8 +spring.mail.host =${MAIL_HOST:smtp.163.com} +spring.mail.port =${MAIL_PORT:465} +spring.mail.username =${MAIL_USER:maxkey@163.com} +spring.mail.password =${MAIL_PWD:password} +spring.mail.protocol =smtp +spring.mail.properties.ssl =true +spring.mail.properties.sender =${MAIL_SENDER:maxkey@163.com} +spring.mail.properties.mailotp.message.subject =MaxKey One Time PassWord +spring.mail.properties.mailotp.message.template ={0} You Token is {1} , it validity in {2} minutes. +spring.mail.properties.mailotp.message.type =html +spring.mail.properties.mailotp.message.validity =300 + +############################################################################ +#Time-based One-Time Password configuration # +############################################################################ +maxkey.otp.policy.type =totp +maxkey.otp.policy.digits =6 +maxkey.otp.policy.issuer =${OTP_POLICY_ISSUER:MaxKey} +maxkey.otp.policy.domain =${maxkey.server.domain} +maxkey.otp.policy.period =30 + +############################################################################# +#SAML V2.0 configuration # +############################################################################# +#saml common +maxkey.saml.v20.max.parser.pool.size =2 +maxkey.saml.v20.assertion.validity.time.ins.seconds =90 +maxkey.saml.v20.replay.cache.life.in.millis =14400000 +maxkey.saml.v20.issue.instant.check.clock.skew.in.seconds =90 +maxkey.saml.v20.issue.instant.check.validity.time.in.seconds =300 +#saml Identity Provider keystore +maxkey.saml.v20.idp.keystore.password =maxkey +maxkey.saml.v20.idp.keystore.private.key.password =maxkey +maxkey.saml.v20.idp.keystore =classpath\:config/samlServerKeystore.jks +#keystore Identity Provider for security +maxkey.saml.v20.idp.issuing.entity.id =maxkey.top +maxkey.saml.v20.idp.issuer =${maxkey.server.authz.uri}/saml +maxkey.saml.v20.idp.receiver.endpoint =https\://sso.maxkey.top/ +#Saml v20 Identity Provider METADATA +maxkey.saml.v20.metadata.orgName =MaxKeyTop +maxkey.saml.v20.metadata.orgDisplayName =MaxKeyTop +maxkey.saml.v20.metadata.orgURL =https://www.maxkey.top +maxkey.saml.v20.metadata.contactType =technical +maxkey.saml.v20.metadata.company =MaxKeyTop +maxkey.saml.v20.metadata.givenName =maxkey +maxkey.saml.v20.metadata.surName =maxkey +maxkey.saml.v20.metadata.emailAddress =maxkeysupport@163.com +maxkey.saml.v20.metadata.telephoneNumber =4008981111 + +#saml RelayParty keystore +maxkey.saml.v20.sp.keystore.password =maxkey +maxkey.saml.v20.sp.keystore.private.key.password =maxkey +maxkey.saml.v20.sp.keystore =classpath\:config/samlClientKeystore.jks +maxkey.saml.v20.sp.issuing.entity.id =client.maxkey.org + +############################################################################# +#OIDC V1.0 METADATA configuration # +############################################################################# +maxkey.oidc.metadata.issuer =${maxkey.server.authz.uri} +maxkey.oidc.metadata.authorizationEndpoint =${maxkey.server.authz.uri}/authz/oauth/v20/authorize +maxkey.oidc.metadata.tokenEndpoint =${maxkey.server.authz.uri}/authz/oauth/v20/token +maxkey.oidc.metadata.userinfoEndpoint =${maxkey.server.authz.uri}/api/connect/userinfo + +############################################################################# +#Job Scheduler # +############################################################################# +#one hour for refresh Schedule +maxkey.job.cron.schedule =0 0 0/1 * * ? +maxkey.job.cron.enable =true + +############################################################################ +#Management endpoints configuration # +############################################################################ +management.security.enabled =false +#management.endpoints.jmx.exposure.include=health,info +#management.endpoints.web.exposure.include=metrics,health,info,env,prometheus +management.endpoints.web.exposure.include =* +management.endpoint.health.show-details =ALWAYS +management.health.redis.enabled =false +management.health.mail.enabled =false + +#Spring Boot Admin Client +spring.boot.admin.client.enabled =${SPRING_BOOT_ADMIN_ENABLED:false} +spring.boot.admin.client.url =${SPRING_BOOT_ADMIN_URL:http://127.0.0.1:9528} +spring.boot.admin.client.username =${SPRING_BOOT_ADMIN_USERNAME:} +spring.boot.admin.client.password =${SPRING_BOOT_ADMIN_PASSWORD:} + +############################################################################ +#Do not modify the following configuration +############################################################################ +#springfox.documentation.swagger.v2.path=/api-docs # +#Swagger Configure Properties # +############################################################################ +maxkey.swagger.enable =true +maxkey.swagger.title =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863 +maxkey.swagger.description =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863 +maxkey.swagger.version =${application.formatted-version} + +springdoc.swagger-ui.path =/swagger-ui.html +springdoc.swagger-ui.enabled =true +springdoc.swagger-ui.tags-sorter =alpha +springdoc.swagger-ui.operations-sorter =alpha +springdoc.swagger-ui.showExtensions =true +springdoc.api-docs.path =/v3/api-docs +springdoc.group-configs[0].group =default +springdoc.group-configs[0].paths-to-match =/* +springdoc.group-configs[0].packages-to-scan =org.maxkey + +knife4j.enable =true +knife4j.setting.language =zh_cn +knife4j.setting.swagger-model-name =\u5B9E\u4F53\u7C7B\u5217\u8868 +############################################################################ +#freemarker configuration # +############################################################################ +spring.freemarker.template-loader-path =classpath:/templates/views +spring.freemarker.cache =false +spring.freemarker.charset =UTF-8 +spring.freemarker.check-template-location =true +spring.freemarker.content-type =text/html +spring.freemarker.expose-request-attributes =false +spring.freemarker.expose-session-attributes =false +spring.freemarker.request-context-attribute =request +spring.freemarker.suffix =.ftl + +############################################################################ +#static resources configuration # +############################################################################ +spring.mvc.static-path-pattern =/static/** + +############################################################################ +#server servlet encoding configuration # +############################################################################ +#encoding +#server.servlet.encoding.charset=UTF-8 +#server.servlet.encoding.enabled=true +#server.servlet.encoding.force=true + +############################################################################ +#Servlet multipart configuration # +############################################################################ +spring.servlet.multipart.enabled =true +spring.servlet.multipart.max-file-size =4194304 \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/application.properties b/maxkey-webs/maxkey-web-openapi/src/main/resources/application.properties new file mode 100644 index 00000000..d1b3b0e3 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/resources/application.properties @@ -0,0 +1,30 @@ +############################################################################ +# Copyright [2022] [MaxKey of copyright http://www.maxkey.top] +# +# 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. +############################################################################ +#MaxKey Title and Version # +############################################################################ +application.title =MaxKey-OpenApi +application.formatted-version =v3.5.18 GA +#for dynamic service discovery +spring.application.name =maxkey-openapi +############################################################################ +#Main.banner-mode configuration # +############################################################################ +spring.main.banner-mode =log +#spring.main.allow-bean-definition-overriding =true +############################################################################ +#spring.profiles.active maxkey-mgt # +############################################################################ +spring.profiles.active =${SERVER_PROFILES:maxkey-openapi} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/bootstrap.properties b/maxkey-webs/maxkey-web-openapi/src/main/resources/bootstrap.properties new file mode 100644 index 00000000..5f403fd1 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/resources/bootstrap.properties @@ -0,0 +1,18 @@ +#nacos config +spring.cloud.nacos.config.server-addr =${NACOS_CONFIG_SERVER_ADDR:127.0.0.1:8848} +# Nacos Console add configuration: +# Data ID:maxkey.properties +# Group:DEFAULT_GROUP +# configuration:useLocalCache=true +spring.application.name =maxkey-mgt +# Suffix for the configuration. Supports properties,yaml,yml,default is properties +spring.cloud.nacos.config.file-extension =properties +#spring.cloud.nacos.config.file-extension=yaml +#nacos enabled +spring.cloud.nacos.config.enabled =${NACOS_CONFIG_ENABLED:false} +spring.cloud.nacos.config.namespace =${NACOS_CONFIG_NAMESPACE:net-maxsso} + +#nacos discovery +spring.cloud.nacos.discovery.enabled =${NACOS_DISCOVERY_ENABLED:false} +spring.cloud.nacos.discovery.server-addr =${NACOS_DISCOVERY_SERVER_ADDR:127.0.0.1:8848} +spring.cloud.nacos.discovery.namespace =${NACOS_DISCOVERY_NAMESPACE:net-maxsso} \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/config/loginjwkkeystore.jwks b/maxkey-webs/maxkey-web-openapi/src/main/resources/config/loginjwkkeystore.jwks new file mode 100644 index 00000000..c06f46ea --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/resources/config/loginjwkkeystore.jwks @@ -0,0 +1,13 @@ +{ + "keys": [ + { + "kty": "RSA", + "d": "K2VCm_6enq5uoFLZXUlWkgbCXj5m9X5uUX3_Ol3qcY9X1cP04TN98R8lpw-ASeFDRFRhe0FT-lYCYu_fqZcrNXVhyN3rgi27af5x4HdFMnHLTLMPvE6aEyTGmZjTF1AbiX5VOJAl6POI9FiyTbV1Uqt943ydJv8SH4NfcYhKBmpp8Fi1f58mon-bYwsIy8mzZjssc8KZy-GzpscKrc5ewb7106JY3uRQNprAHrpcGAPZ8uXUvVhrxp_FNn5Nf5KVxl2tm50L83_5nw0OZrbJ8Ceg7sZAw_Z41lbYbS9VDaST6TuKRb7W4XCKimZUn57LoQT2-Gkv6msJHCmqTgK02Q", + "e": "AQAB", + "use": "sig", + "kid": "maxkey_rsa", + "alg": "RS256", + "n": "vyfZwQuBLNvJDhmziUCFuAfIv-bC6ivodcR6PfanTt8XLd6G63Yx10YChAdsDACjoLz1tEU56WPp_ee_vcTSsEZT3ouWJYghuGI2j4XclXlEj0S7DzdpcBBpI4n5dr8K3iKY-3JUMZR1AMBHI50UaMST9ZTZJAjUPIYxkhRdca5lWBo4wGUh1yj_80-Bq6al0ia9S5NTzNLaJ18jSxFqZ79BAkBm-KjkP248YUk6WBGtYEAV5Fws4dpse4hrqJ3RRHiMZV1o1iTmPHz_l55ZSDP3vpYf6iKqKzoK2RmdjfH5mGpbc4-PclTs4GKfwZ7cWfrny6B7sMnQfzujCH996Q" + } + ] +} diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlClientKeystore.jks b/maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlClientKeystore.jks new file mode 100644 index 00000000..c94ae417 Binary files /dev/null and b/maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlClientKeystore.jks differ diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlServerKeystore.jks b/maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlServerKeystore.jks new file mode 100644 index 00000000..29945eaf Binary files /dev/null and b/maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlServerKeystore.jks differ diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/log4j2.xml b/maxkey-webs/maxkey-web-openapi/src/main/resources/log4j2.xml new file mode 100644 index 00000000..2c3c0684 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/resources/log4j2.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/static/favicon.ico b/maxkey-webs/maxkey-web-openapi/src/main/resources/static/favicon.ico new file mode 100644 index 00000000..485a4a4a Binary files /dev/null and b/maxkey-webs/maxkey-web-openapi/src/main/resources/static/favicon.ico differ diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/templates/views/index.ftl b/maxkey-webs/maxkey-web-openapi/src/main/resources/templates/views/index.ftl new file mode 100644 index 00000000..a443d20a --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/resources/templates/views/index.ftl @@ -0,0 +1,21 @@ + + + + + + + MaxKey Single Sign-On + + +
+
+ Maxkey Community Edition
+ Single Sign On ( SSO )
+ Version ${appVersion}
+
+ ©Copyright 2018 - ${.now?string["yyyy"]} https://www.maxkey.top/
+ Licensed under the Apache License, Version 2.0
+
+
+ + diff --git a/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/maxkey-mgt-servlet.xml b/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/maxkey-mgt-servlet.xml new file mode 100644 index 00000000..59788833 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/maxkey-mgt-servlet.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.backup.xml b/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.backup.xml new file mode 100644 index 00000000..e06b3432 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.backup.xml @@ -0,0 +1,169 @@ + + + + MaxKey Management + + + webAppRootKey + org.maxkey.management.root + + + + InitWebContext + org.maxkey.web.InitWebContext + 1 + + + + + + contextConfigLocation + /WEB-INF/spring/maxkey-mgt.xml + + + + + log4jRefreshInterval + 60000 + + + + org.springframework.web.context.request.RequestContextListener + + + org.springframework.web.context.ContextLoaderListener + + + org.springframework.web.util.IntrospectorCleanupListener + + + + + isLog4jAutoInitializationDisabled + false + + + + log4jConfiguration + classpath:log4j2.xml + + + + + org.apache.logging.log4j.web.Log4jServletContextListener + + + + log4jServletFilter + org.apache.logging.log4j.web.Log4jServletFilter + + + log4jServletFilter + /* + REQUEST + FORWARD + INCLUDE + ERROR + + + + characterEncodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + forceEncoding + true + + + + characterEncodingFilter + /* + + + + + maxkey-mgt + org.springframework.web.servlet.DispatcherServlet + 1 + + + maxkey-mgt + / + + + HiddenHttpMethodFilter + org.springframework.web.filter.HiddenHttpMethodFilter + + + HiddenHttpMethodFilter + maxkey-mgt + + + + + 30 + + + + + 401 + /WEB-INF/view/exception/accessdeny.jsp + + + + 403 + /WEB-INF/view/exception/accessdeny.jsp + + + + 404 + /WEB-INF/view/exception/404.jsp + + + + 500 + /WEB-INF/view/exception/500.jsp + + + + 501 + /WEB-INF/view/exception/501.jsp + + + + 503 + /WEB-INF/view/exception/503.jsp + + + + + + http://sso.maxkey.org/tags + /WEB-INF/tags/maxkeyTag.tld + + + http://java.sun.com/jsp/jstl/core + /WEB-INF/tags/c.tld + + + diff --git a/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.xml b/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..0e1f8b09 --- /dev/null +++ b/maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + + + MaxKey Management + + + webAppRootKey + org.maxkey.management.root + + + diff --git a/settings.gradle b/settings.gradle index 2b37d1aa..962060f1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -54,10 +54,12 @@ include ( 'maxkey-protocols:maxkey-protocol-tokenbased', 'maxkey-protocols:maxkey-protocol-extendapi', //webs - //maxkey + //gataway + 'maxkey-webs:maxkey-gataway', + //maxkey(sign) 'maxkey-webs:maxkey-web-maxkey', //management(mgt) 'maxkey-webs:maxkey-web-mgt', - //gataway - 'maxkey-webs:maxkey-gataway' + //openapi(open) + 'maxkey-webs:maxkey-web-openapi', ) \ No newline at end of file