瀏覽代碼

add openapi service

MaxKey 2 年之前
父節點
當前提交
4b1c88c1a2
共有 30 個文件被更改,包括 1439 次插入10 次删除
  1. 4 4
      gradle.properties
  2. 1 1
      maxkey-webs/maxkey-gataway/src/main/resources/application.yml
  3. 1 1
      maxkey-webs/maxkey-web-maxkey/src/main/resources/application.properties
  4. 1 1
      maxkey-webs/maxkey-web-mgt/src/main/resources/application.properties
  5. 24 0
      maxkey-webs/maxkey-web-openapi/build.gradle
  6. 59 0
      maxkey-webs/maxkey-web-openapi/config/build_docker.gradle
  7. 59 0
      maxkey-webs/maxkey-web-openapi/config/build_jar.gradle
  8. 24 0
      maxkey-webs/maxkey-web-openapi/config/build_standard.gradle
  9. 2 0
      maxkey-webs/maxkey-web-openapi/src/main/java/META-INF/MANIFEST.MF
  10. 82 0
      maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/MaxKeyOpenApiApplication.java
  11. 73 0
      maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiConfig.java
  12. 144 0
      maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/MaxKeyOpenApiMvcConfig.java
  13. 121 0
      maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/autoconfigure/Oauth20ClientAutoConfiguration.java
  14. 60 0
      maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/api/endpoint/RestTimeBasedOtpController.java
  15. 80 0
      maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java
  16. 112 0
      maxkey-webs/maxkey-web-openapi/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java
  17. 14 0
      maxkey-webs/maxkey-web-openapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  18. 258 0
      maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties
  19. 30 0
      maxkey-webs/maxkey-web-openapi/src/main/resources/application.properties
  20. 18 0
      maxkey-webs/maxkey-web-openapi/src/main/resources/bootstrap.properties
  21. 13 0
      maxkey-webs/maxkey-web-openapi/src/main/resources/config/loginjwkkeystore.jwks
  22. 二進制
      maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlClientKeystore.jks
  23. 二進制
      maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlServerKeystore.jks
  24. 36 0
      maxkey-webs/maxkey-web-openapi/src/main/resources/log4j2.xml
  25. 二進制
      maxkey-webs/maxkey-web-openapi/src/main/resources/static/favicon.ico
  26. 21 0
      maxkey-webs/maxkey-web-openapi/src/main/resources/templates/views/index.ftl
  27. 11 0
      maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/maxkey-mgt-servlet.xml
  28. 169 0
      maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.backup.xml
  29. 17 0
      maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.xml
  30. 5 3
      settings.gradle

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

+ 1 - 1
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:

+ 1 - 1
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
 ############################################################################

+ 1 - 1
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
 ############################################################################

+ 24 - 0
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")
+   		   	
+}

+ 59 - 0
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")	
+   	
+}

+ 59 - 0
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")	
+}

+ 24 - 0
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")	
+
+}

+ 2 - 0
maxkey-webs/maxkey-web-openapi/src/main/java/META-INF/MANIFEST.MF

@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+

+ 82 - 0
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);
+	}
+
+}

+ 73 - 0
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 {
+        
+    }
+
+}

+ 144 - 0
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<HandlerMethodArgumentResolver> argumentResolvers) {
+        argumentResolvers.add(currentUserMethodArgumentResolver());
+    }
+    
+    @Bean
+    public CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() {
+        return new CurrentUserMethodArgumentResolver();
+    }
+
+}

+ 121 - 0
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 {
+        
+    }
+
+}

+ 60 - 0
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;
+    }
+
+ 
+}

+ 80 - 0
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  ConcurrentHashMap<String ,String >navigationsMap=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;
+	}
+}

+ 112 - 0
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  ConcurrentHashMap<String ,String >navigationsMap=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;
+	}
+}

+ 14 - 0
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

+ 258 - 0
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

+ 30 - 0
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}

+ 18 - 0
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}

+ 13 - 0
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"
+    }
+  ]
+}

二進制
maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlClientKeystore.jks


二進制
maxkey-webs/maxkey-web-openapi/src/main/resources/config/samlServerKeystore.jks


+ 36 - 0
maxkey-webs/maxkey-web-openapi/src/main/resources/log4j2.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>  
+<Configuration status="INFO"  monitorInterval="300">  
+    <Appenders>      	
+        <Console name="consolePrint" target="SYSTEM_OUT">  
+            <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level [%t] %logger{36}:%L - %msg%n" />  
+        </Console>
+        
+		<!-- 输出到文件,按天或者超过128MB分割 -->
+		<RollingFile name="RollingFile" fileName="logs/maxkey_openapi.log"    filePattern="logs/$${date:yyyyMMdd}/maxkey-openapi-%d{yyyy-MM-dd}-%i.log.gz">
+		    <!-- 需要记录的级别 -->
+		 	<!-- <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> -->
+		     <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5level [%t] (%logger{36}:%L) - %msg%n" />
+		     <Policies>
+		          <OnStartupTriggeringPolicy />
+		          <TimeBasedTriggeringPolicy />
+		          <SizeBasedTriggeringPolicy size="128 MB" />
+		     </Policies>
+		     <DefaultRolloverStrategy max="100"/>
+		</RollingFile>
+	 </Appenders>  
+	 
+    <Loggers>  
+    	<Logger level="INFO" 	name="org.springframework" ></Logger>
+    	<Logger level="INFO" 	name="org.apache.logging" ></Logger>
+    	<Logger level="DEBUG" 	name="org.maxkey" ></Logger>
+    	<Logger level="DEBUG"	name="org.apache.mybatis.jpa" ></Logger>
+    	<Logger level="ERROR"	name="org.reflections.Reflections" ></Logger>
+    	<Logger level="ERROR"   name="RocketmqRemoting" ></Logger>
+    	<Logger level="OFF"     name="org.hibernate.validator.internal.util.Version" ></Logger>
+    	
+        <Root level="INFO">  
+            <AppenderRef ref="consolePrint" />
+            <AppenderRef ref="RollingFile" /> 
+        </Root>  
+    </Loggers>  
+</Configuration>

二進制
maxkey-webs/maxkey-web-openapi/src/main/resources/static/favicon.ico


+ 21 - 0
maxkey-webs/maxkey-web-openapi/src/main/resources/templates/views/index.ftl

@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html >
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <link rel="shortcut icon" type="image/x-icon" href="<@base />/static/favicon.ico"/>
+    <base href="<@base />"/>
+    <title>MaxKey Single Sign-On</title>
+</head>
+<body>
+    <center>
+        <hr>
+        Maxkey Community  Edition <br>
+        Single   Sign  On ( SSO ) <br>
+        Version ${appVersion}<br>
+        <br>
+        ©Copyright 2018 - ${.now?string["yyyy"]} https://www.maxkey.top/<br>
+        Licensed under the Apache License, Version 2.0 <br>
+        <hr>
+    </center>
+</body>
+</html>

+ 11 - 0
maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/maxkey-mgt-servlet.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<beans 	xmlns="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xsi:schemaLocation="
+	        http://www.springframework.org/schema/beans 
+			http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<!-- This file has been left blank -->
+	<!-- See WEB-INF spring package -->		
+		
+</beans>

+ 169 - 0
maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.backup.xml

@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
+		 xmlns:javaee="http://java.sun.com/xml/ns/javaee" 
+		 xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" 
+		 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
+		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+		 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
+		 version="2.4">
+		 
+   <display-name>MaxKey Management</display-name>
+   <!-- webAppRootKey -->
+   <context-param>
+      <param-name>webAppRootKey</param-name>
+      <param-value>org.maxkey.management.root</param-value>
+   </context-param>
+   
+   <servlet>
+    <servlet-name>InitWebContext</servlet-name>
+    <servlet-class>org.maxkey.web.InitWebContext</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <!-- 
+  <servlet-mapping>
+    <servlet-name>InitWebContext</servlet-name>
+    <url-pattern>/</url-pattern>
+  </servlet-mapping> -->
+  
+   <!-- contextConfigLocation -->
+   <context-param>
+      <param-name>contextConfigLocation</param-name>
+      <param-value>/WEB-INF/spring/maxkey-mgt.xml</param-value>
+   </context-param>
+   
+   <!-- log4jConfigLocation
+   <context-param>
+      <param-name>log4jConfigLocation</param-name>
+      <param-value>classpath:log4j.properties</param-value>
+   </context-param> -->
+   <context-param>
+      <param-name>log4jRefreshInterval</param-name>
+      <param-value>60000</param-value>
+   </context-param>
+   <!-- listeners 
+   <listener>
+      <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
+   </listener>-->
+   <listener>
+      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
+   </listener>
+   <listener>
+      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+   </listener>
+   <listener>
+      <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
+   </listener>
+   
+   <!-- log4j -->
+    <context-param>  
+        <param-name>isLog4jAutoInitializationDisabled</param-name>  
+        <param-value>false</param-value>  
+    </context-param>  
+    <!-- 默认就会找这个文件,不需要额外配置引用  -->
+    <context-param>  
+        <param-name>log4jConfiguration</param-name>  
+        <param-value>classpath:log4j2.xml</param-value>  
+    </context-param>  
+   
+	<!-- 在WEB项目中使用log4j2需要在web.xml文件中配置如下的监听器和过滤器 -->
+    <listener>  
+        <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>  
+    </listener>  
+   
+    <filter>  
+        <filter-name>log4jServletFilter</filter-name>  
+        <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>  
+    </filter>  
+    <filter-mapping>  
+        <filter-name>log4jServletFilter</filter-name>  
+        <url-pattern>/*</url-pattern>  
+        <dispatcher>REQUEST</dispatcher>  
+        <dispatcher>FORWARD</dispatcher>  
+        <dispatcher>INCLUDE</dispatcher>  
+        <dispatcher>ERROR</dispatcher>  
+	</filter-mapping>  
+    <!-- CharacterEncodingFilter -->
+	<filter>  
+		<filter-name>characterEncodingFilter</filter-name>  
+    	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
+    	<init-param>  
+	        <param-name>encoding</param-name>  
+	        <param-value>UTF-8</param-value>  
+    	</init-param>  
+	    <init-param>  
+	        <param-name>forceEncoding</param-name>  
+	        <param-value>true</param-value>  
+	    </init-param>  
+	</filter>  
+	<filter-mapping>  
+	    <filter-name>characterEncodingFilter</filter-name>  
+	    <url-pattern>/*</url-pattern>  
+	</filter-mapping>  
+
+    <!-- DispatcherServlet Spring MVC -->
+   <servlet>
+      <servlet-name>maxkey-mgt</servlet-name>
+      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+      <load-on-startup>1</load-on-startup>
+   </servlet>
+   <servlet-mapping>
+      <servlet-name>maxkey-mgt</servlet-name>
+      <url-pattern>/</url-pattern>
+   </servlet-mapping>
+	<filter>
+	   	<filter-name>HiddenHttpMethodFilter</filter-name>
+	   <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
+	</filter>
+	<filter-mapping>
+	   <filter-name>HiddenHttpMethodFilter</filter-name>
+	   <servlet-name>maxkey-mgt</servlet-name>
+	</filter-mapping>
+
+   <!-- default session timeout  30 minutes -->
+   <session-config>
+		<session-timeout>30</session-timeout>
+   </session-config>
+
+	<!--Error page config -->
+  	<error-page>
+   		<error-code>401</error-code>
+    	<location>/WEB-INF/view/exception/accessdeny.jsp</location>
+  	</error-page>
+
+	<error-page>
+    	<error-code>403</error-code>
+    	<location>/WEB-INF/view/exception/accessdeny.jsp</location>
+  	</error-page>
+
+  	<error-page>
+    	<error-code>404</error-code>
+    	<location>/WEB-INF/view/exception/404.jsp</location>
+  	</error-page>
+
+  	<error-page>
+    	<error-code>500</error-code>
+    	<location>/WEB-INF/view/exception/500.jsp</location>
+  	</error-page>
+
+ 	<error-page>
+   		<error-code>501</error-code>
+    	<location>/WEB-INF/view/exception/501.jsp</location>
+  	</error-page>
+
+  	<error-page>
+   	 <error-code>503</error-code>
+   	 <location>/WEB-INF/view/exception/503.jsp</location>
+  	</error-page>
+  
+  	<!--used jsp Tag -->
+   <jsp-config>
+      <taglib>
+         <taglib-uri>http://sso.maxkey.org/tags</taglib-uri>
+         <taglib-location>/WEB-INF/tags/maxkeyTag.tld</taglib-location>
+      </taglib>
+      <taglib>
+         <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
+         <taglib-location>/WEB-INF/tags/c.tld</taglib-location>
+      </taglib>
+   </jsp-config>
+</web-app>

+ 17 - 0
maxkey-webs/maxkey-web-openapi/src/main/webapp/WEB-INF/web.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
+		 xmlns:javaee="http://java.sun.com/xml/ns/javaee" 
+		 xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" 
+		 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
+		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+		 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
+		 version="2.4">
+		 
+   <display-name>MaxKey Management</display-name>
+   <!-- webAppRootKey -->
+   <context-param>
+      <param-name>webAppRootKey</param-name>
+      <param-value>org.maxkey.management.root</param-value>
+   </context-param>
+   
+</web-app>

+ 5 - 3
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',
 )