Jelajahi Sumber

代码优化

MaxKey 7 bulan lalu
induk
melakukan
d397012e78

+ 0 - 2
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/resources/META-INF/spring.handlers

@@ -1,2 +0,0 @@
-http\://www.springframework.org/schema/security/oauth2=org.springframework.security.oauth2.config.xml.OAuth2SecurityNamespaceHandler
-http\://www.springframework.org/schema/security/oauth=org.springframework.security.oauth.config.OAuthSecurityNamespaceHandler

+ 0 - 5
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/resources/META-INF/spring.schemas

@@ -1,5 +0,0 @@
-http\://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd=org/springframework/security/oauth2/spring-security-oauth2-1.0.xsd
-http\://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd=org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd
-http\://www.springframework.org/schema/security/spring-security-oauth2.xsd=org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd
-http\://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd=org/springframework/security/oauth/spring-security-oauth-1.0.xsd
-http\://www.springframework.org/schema/security/spring-security-oauth.xsd=org/springframework/security/oauth/spring-security-oauth-1.0.xsd

+ 1 - 0
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+org.dromara.maxkey.autoconfigure.Oauth20AutoConfiguration

+ 5 - 5
maxkey-webs/maxkey-web-maxkey/src/main/java/org/dromara/maxkey/MaxKeyApplication.java

@@ -37,22 +37,22 @@ import org.springframework.context.ConfigurableApplicationContext;
 @EnableDiscoveryClient
 @MapperScan("org.dromara.maxkey.persistence.mapper,")
 public class MaxKeyApplication extends SpringBootServletInitializer {
-    private static final Logger logger = LoggerFactory.getLogger(MaxKeyApplication.class);
+    static final Logger _logger = LoggerFactory.getLogger(MaxKeyApplication.class);
 
     /**
      * @param args start parameter 
      */
     public static void main(String[] args) {
-        logger.info("Start MaxKey Application ...");
+    	_logger.info("Start MaxKey Application ...");
         ProductEnvironment.listEnvVars();
         
         VFS.addImplClass(SpringBootVFS.class);
         ConfigurableApplicationContext applicationContext = SpringApplication.run(MaxKeyApplication.class, args);
         new InitializeContext(applicationContext).init();
         
-        logger.info("MaxKey at {}" , new DateTime());
-        logger.info("MaxKey Server Port {}" , WebContext.getProperty("server.port"));
-        logger.info("MaxKey started.");
+        _logger.info("MaxKey at {}" , new DateTime());
+        _logger.info("MaxKey Server Port {}" , WebContext.getProperty("server.port"));
+        _logger.info("MaxKey started.");
     }
 
     @Override

+ 1 - 0
maxkey-webs/maxkey-web-mgt/build.gradle

@@ -53,6 +53,7 @@ dependencies {
 	implementation project(":maxkey-authentications:maxkey-authentication-core")
 	implementation project(":maxkey-authentications:maxkey-authentication-provider")
 	
+	implementation project(":maxkey-protocols:maxkey-protocol-authorize")
    	implementation project(":maxkey-protocols:maxkey-protocol-oauth-2.0")
    	implementation project(":maxkey-protocols:maxkey-protocol-saml-2.0")   
 	

+ 6 - 29
maxkey-webs/maxkey-web-mgt/src/main/java/org/dromara/maxkey/MaxKeyMgtApplication.java

@@ -30,46 +30,23 @@ 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.dromara.maxkey.authn",
-	"org.dromara.maxkey.configuration",
-	"org.dromara.maxkey.entity",
-    "org.dromara.maxkey.entity.apps",
-    "org.dromara.maxkey.entity.userinfo",
-    "org.dromara.maxkey.web.apis.identity.kafka",
-    "org.dromara.maxkey.web.apis.identity.rest",
-    "org.dromara.maxkey.web.apis.identity.scim",
-    "org.dromara.maxkey.persistence",
-    "org.dromara.maxkey.provision",
-    "org.dromara.maxkey.synchronizer",
-    "org.dromara.maxkey.web",
-    "org.dromara.maxkey.web.access.contorller", 
-    "org.dromara.maxkey.web.api.endpoint",
-    "org.dromara.maxkey.web.apps.contorller",
-    "org.dromara.maxkey.web.contorller",
-    "org.dromara.maxkey.web.endpoint",
-    "org.dromara.maxkey.web.interceptor",
-    "org.dromara.maxkey.web.permissions.contorller", 
-    "org.dromara.maxkey.web.tag"
-})
-@MapperScan("org.dromara.maxkey.persistence.mapper,")
 @SpringBootApplication
 @EnableDiscoveryClient
+@MapperScan("org.dromara.maxkey.persistence.mapper,")
 public class MaxKeyMgtApplication extends SpringBootServletInitializer {
-	private static final Logger logger = LoggerFactory.getLogger(MaxKeyMgtApplication.class);
+	static final Logger _logger = LoggerFactory.getLogger(MaxKeyMgtApplication.class);
 
 	public static void main(String[] args) {
-	    logger.info("Start MaxKeyMgt Application ...");
+		_logger.info("Start MaxKeyMgt Application ...");
 	    ProductEnvironment.listEnvVars();
 	    
 		ConfigurableApplicationContext  applicationContext = SpringApplication.run(MaxKeyMgtApplication.class, args);
 		new InitializeContext(applicationContext).init();
 		
-		logger.info("MaxKeyMgt at {}" , new DateTime());
-		logger.info("MaxKeyMgt Server Port {}" , WebContext.getProperty("server.port"));
-		logger.info("MaxKeyMgt started.");
+		_logger.info("MaxKeyMgt at {}" , new DateTime());
+		_logger.info("MaxKeyMgt Server Port {}" , WebContext.getProperty("server.port"));
+		_logger.info("MaxKeyMgt started.");
 		
 	}
 

+ 0 - 117
maxkey-webs/maxkey-web-mgt/src/main/java/org/dromara/maxkey/autoconfigure/Oauth20ClientAutoConfiguration.java

@@ -1,117 +0,0 @@
-/*
- * 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.dromara.maxkey.autoconfigure;
-
-import javax.sql.DataSource;
-
-import org.dromara.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService;
-import org.dromara.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService;
-import org.dromara.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
-import org.dromara.maxkey.authz.oauth2.provider.token.TokenStore;
-import org.dromara.maxkey.authz.oauth2.provider.token.store.InMemoryTokenStore;
-import org.dromara.maxkey.authz.oauth2.provider.token.store.RedisTokenStore;
-import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Qualifier;
-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 {
-    private static final  Logger logger = LoggerFactory.getLogger(Oauth20ClientAutoConfiguration.class);
-
-    @Bean
-    JdbcClientDetailsService oauth20JdbcClientDetailsService(
-                DataSource dataSource, @Qualifier("passwordReciprocal") PasswordEncoder passwordReciprocal) {
-	    JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
-	    //clientDetailsService.setPasswordEncoder(passwordReciprocal);
-	    logger.debug("JdbcClientDetailsService inited.");
-        return clientDetailsService;
-    }
-
-    /**
-     * TokenStore. 
-     * @param persistence int
-     * @return oauth20TokenStore
-     */
-    @Bean
-    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
-    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
-    ProviderManager oauth20ClientAuthenticationManager(
-            JdbcClientDetailsService oauth20JdbcClientDetailsService,
-            @Qualifier("passwordReciprocal")
-            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;
-    }
-  
-}

+ 0 - 1
maxkey-webs/maxkey-web-mgt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -1,4 +1,3 @@
-org.dromara.maxkey.autoconfigure.Oauth20ClientAutoConfiguration
 org.dromara.maxkey.autoconfigure.MaxKeyMgtConfig
 org.dromara.maxkey.autoconfigure.MaxKeyMgtMvcConfig
 org.dromara.maxkey.autoconfigure.MaxKeyMgtListenerConfig

+ 13 - 0
maxkey-webs/maxkey-web-mgt/src/main/resources/config/keystore.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"
+    }
+  ]
+}

+ 1 - 0
maxkey-webs/maxkey-web-openapi/build.gradle

@@ -53,6 +53,7 @@ dependencies {
 	implementation project(":maxkey-authentications:maxkey-authentication-core")
 	implementation project(":maxkey-authentications:maxkey-authentication-provider")
 	
+	implementation project(":maxkey-protocols:maxkey-protocol-authorize")
    	implementation project(":maxkey-protocols:maxkey-protocol-oauth-2.0")
    	implementation project(":maxkey-protocols:maxkey-protocol-saml-2.0")   
    	

+ 6 - 24
maxkey-webs/maxkey-web-openapi/src/main/java/org/dromara/maxkey/MaxKeyOpenApiApplication.java

@@ -31,41 +31,23 @@ 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.dromara.maxkey.authn",
-	"org.dromara.maxkey.configuration",
-	"org.dromara.maxkey.entity",
-    "org.dromara.maxkey.entity.apps",
-    "org.dromara.maxkey.entity.userinfo",
-    "org.dromara.maxkey.web.apis.identity.kafka",
-    "org.dromara.maxkey.web.apis.identity.rest",
-    "org.dromara.maxkey.web.apis.identity.scim",
-    "org.dromara.maxkey.persistence",
-    "org.dromara.maxkey.provision",
-    "org.dromara.maxkey.web",
-    "org.dromara.maxkey.web.api.endpoint",
-    "org.dromara.maxkey.web.contorller",
-    "org.dromara.maxkey.web.endpoint",
-    "org.dromara.maxkey.web.interceptor",
-})
-@MapperScan("org.dromara.maxkey.persistence.mapper,")
 @SpringBootApplication
 @EnableDiscoveryClient
+@MapperScan("org.dromara.maxkey.persistence.mapper,")
 public class MaxKeyOpenApiApplication extends SpringBootServletInitializer {
-	private static final Logger logger = LoggerFactory.getLogger(MaxKeyOpenApiApplication.class);
+	static final Logger _logger = LoggerFactory.getLogger(MaxKeyOpenApiApplication.class);
 
 	public static void main(String[] args) {
-	    logger.info("Start MaxKey OpenApi Application ...");
+		_logger.info("Start MaxKey OpenApi Application ...");
 	    ProductEnvironment.listEnvVars();
 	    
 		ConfigurableApplicationContext  applicationContext = SpringApplication.run(MaxKeyOpenApiApplication.class, args);
 		new InitializeContext(applicationContext).init();
 		
-		logger.info("MaxKey OpenApi at {}" , new DateTime());
-		logger.info("MaxKey OpenApi Server Port {}" , WebContext.getProperty("server.port"));
-		logger.info("MaxKey OpenApi started.");
+		_logger.info("MaxKey OpenApi at {}" , new DateTime());
+		_logger.info("MaxKey OpenApi Server Port {}" , WebContext.getProperty("server.port"));
+		_logger.info("MaxKey OpenApi started.");
 		
 	}
 

+ 0 - 117
maxkey-webs/maxkey-web-openapi/src/main/java/org/dromara/maxkey/autoconfigure/Oauth20ClientAutoConfiguration.java

@@ -1,117 +0,0 @@
-/*
- * Copyright [2023] [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.dromara.maxkey.autoconfigure;
-
-import javax.sql.DataSource;
-
-import org.dromara.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService;
-import org.dromara.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService;
-import org.dromara.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
-import org.dromara.maxkey.authz.oauth2.provider.token.TokenStore;
-import org.dromara.maxkey.authz.oauth2.provider.token.store.InMemoryTokenStore;
-import org.dromara.maxkey.authz.oauth2.provider.token.store.RedisTokenStore;
-import org.dromara.maxkey.persistence.redis.RedisConnectionFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Qualifier;
-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 {
-    private static final  Logger logger = LoggerFactory.getLogger(Oauth20ClientAutoConfiguration.class);
-
-    @Bean
-    JdbcClientDetailsService oauth20JdbcClientDetailsService(
-                DataSource dataSource, @Qualifier("passwordReciprocal") PasswordEncoder passwordReciprocal) {
-	    JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
-	    //clientDetailsService.setPasswordEncoder(passwordReciprocal);
-	    logger.debug("JdbcClientDetailsService inited.");
-        return clientDetailsService;
-    }
-
-    /**
-     * TokenStore. 
-     * @param persistence int
-     * @return oauth20TokenStore
-     */
-    @Bean
-    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
-    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
-    ProviderManager oauth20ClientAuthenticationManager(
-            JdbcClientDetailsService oauth20JdbcClientDetailsService,
-            @Qualifier("passwordReciprocal")
-            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;
-    }
-
-}

+ 0 - 1
maxkey-webs/maxkey-web-openapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -1,3 +1,2 @@
-org.dromara.maxkey.autoconfigure.Oauth20ClientAutoConfiguration
 org.dromara.maxkey.autoconfigure.MaxKeyOpenApiConfig
 org.dromara.maxkey.autoconfigure.MaxKeyOpenApiMvcConfig

+ 13 - 0
maxkey-webs/maxkey-web-openapi/src/main/resources/config/keystore.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"
+    }
+  ]
+}