From 9020bb9d6e9352753d7fecdad998da933185b5c5 Mon Sep 17 00:00:00 2001 From: KomachiSion Date: Wed, 26 Jan 2022 11:54:52 +0800 Subject: [PATCH] Move plugin config to nacos-auth-plugin-impl module. --- auth/pom.xml | 15 ---- .../nacos/auth/config/AuthConfigs.java | 78 +++++++++---------- .../nacos/auth/config/AuthConfigsTest.java | 1 + .../src/main/resources/application.properties | 21 +++-- distribution/conf/application.properties | 20 ++--- .../plugin/auth/impl/JwtTokenManager.java | 12 +-- .../plugin/auth/impl/NacosAuthConfig.java | 44 +++++++++++ .../auth/impl/NacosAuthPluginService.java | 4 +- .../auth/impl/constant/AuthConstants.java | 10 +++ .../auth/impl/controller/UserController.java | 6 +- .../impl/controller/UserControllerTest.java | 7 +- sys/pom.xml | 4 + .../nacos/sys/utils/PropertiesUtil.java | 64 +++++++++++++++ .../nacos/sys/utils/PropertiesUtilTest.java | 72 +++++++++++++++++ .../resources/application-prefix.properties | 20 +++++ 15 files changed, 290 insertions(+), 88 deletions(-) create mode 100644 sys/src/main/java/com/alibaba/nacos/sys/utils/PropertiesUtil.java create mode 100644 sys/src/test/java/com/alibaba/nacos/sys/utils/PropertiesUtilTest.java create mode 100644 sys/src/test/resources/application-prefix.properties diff --git a/auth/pom.xml b/auth/pom.xml index fae96dff4..ef110818c 100644 --- a/auth/pom.xml +++ b/auth/pom.xml @@ -59,21 +59,6 @@ org.apache.tomcat.embed tomcat-embed-core - - - io.jsonwebtoken - jjwt-api - - - io.jsonwebtoken - jjwt-impl - runtime - - - io.jsonwebtoken - jjwt-jackson - runtime - diff --git a/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java b/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java index cd47d7556..ba7929da1 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java @@ -16,23 +16,24 @@ package com.alibaba.nacos.auth.config; -import com.alibaba.nacos.plugin.auth.constant.Constants; import com.alibaba.nacos.common.JustForTest; import com.alibaba.nacos.common.event.ServerConfigChangeEvent; import com.alibaba.nacos.common.notify.Event; import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.common.utils.ConvertUtils; +import com.alibaba.nacos.plugin.auth.constant.Constants; import com.alibaba.nacos.sys.env.EnvUtil; -import io.jsonwebtoken.io.Decoders; -import io.jsonwebtoken.io.DecodingException; +import com.alibaba.nacos.sys.utils.PropertiesUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; -import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; +import java.util.Properties; /** * Auth related configurations. @@ -46,6 +47,8 @@ public class AuthConfigs extends Subscriber { private static final Logger LOGGER = LoggerFactory.getLogger(AuthConfigs.class); + private static final String PREFIX = "nacos.core.auth.plugin"; + @JustForTest private static Boolean cachingEnabled = null; @@ -55,23 +58,6 @@ public class AuthConfigs extends Subscriber { @Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLED + ":false}") private boolean authEnabled; - /** - * secret key. - */ - @Value("${" + Constants.Auth.NACOS_CORE_AUTH_DEFAULT_TOKEN_SECRET_KEY + ":}") - private String secretKey; - - /** - * secret key byte array. - */ - private byte[] secretKeyBytes; - - /** - * Token validity time(seconds). - */ - @Value("${" + Constants.Auth.NACOS_CORE_AUTH_DEFAULT_TOKEN_EXPIRE_SECONDS + ":18000}") - private long tokenValidityInSeconds; - /** * Which auth system is in use. */ @@ -87,24 +73,30 @@ public class AuthConfigs extends Subscriber { @Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE + ":false}") private boolean enableUserAgentAuthWhite; + private Map authPluginProperties = new HashMap<>(); + public AuthConfigs() { NotifyCenter.registerSubscriber(this); + refreshPluginProperties(); } - public byte[] getSecretKeyBytes() { - if (secretKeyBytes == null) { - try { - secretKeyBytes = Decoders.BASE64.decode(secretKey); - } catch (DecodingException e) { - secretKeyBytes = secretKey.getBytes(StandardCharsets.UTF_8); + private void refreshPluginProperties() { + try { + Map newProperties = new HashMap<>(); + Properties properties = PropertiesUtil.getPropertiesWithPrefix(EnvUtil.getEnvironment(), PREFIX); + for (String each : properties.stringPropertyNames()) { + int typeIndex = each.indexOf('.'); + String type = each.substring(0, typeIndex); + if (!newProperties.containsKey(type)) { + newProperties.put(type, new Properties()); + } + String subKey = each.substring(typeIndex + 1); + newProperties.get(type).setProperty(subKey, properties.getProperty(each)); } - + authPluginProperties = newProperties; + } catch (Exception e) { + LOGGER.warn("Refresh plugin properties failed ", e); } - return secretKeyBytes; - } - - public long getTokenValidityInSeconds() { - return tokenValidityInSeconds; } public String getNacosAuthSystemType() { @@ -141,8 +133,15 @@ public class AuthConfigs extends Subscriber { if (Objects.nonNull(AuthConfigs.cachingEnabled)) { return cachingEnabled; } - return ConvertUtils.toBoolean( - EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, "true")); + return ConvertUtils.toBoolean(EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, "true")); + } + + public Properties getAuthPluginProperties(String authType) { + if (!authPluginProperties.containsKey(authType)) { + LOGGER.warn("Can't find properties for type {}, will use empty properties", authType); + return new Properties(); + } + return authPluginProperties.get(authType); } @JustForTest @@ -154,14 +153,13 @@ public class AuthConfigs extends Subscriber { public void onEvent(ServerConfigChangeEvent event) { try { authEnabled = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_ENABLED, Boolean.class, false); - cachingEnabled = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, Boolean.class, - true); + cachingEnabled = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_CACHING_ENABLED, Boolean.class, true); serverIdentityKey = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_KEY, ""); serverIdentityValue = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_VALUE, ""); - enableUserAgentAuthWhite = EnvUtil.getProperty( - Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE, Boolean.class, - false); + enableUserAgentAuthWhite = EnvUtil + .getProperty(Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE, Boolean.class, false); nacosAuthSystemType = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SYSTEM_TYPE, ""); + refreshPluginProperties(); } catch (Exception e) { LOGGER.warn("Upgrade auth config from env failed, use old value", e); } diff --git a/auth/src/test/java/com/alibaba/nacos/auth/config/AuthConfigsTest.java b/auth/src/test/java/com/alibaba/nacos/auth/config/AuthConfigsTest.java index 73014398b..94db1a2ce 100644 --- a/auth/src/test/java/com/alibaba/nacos/auth/config/AuthConfigsTest.java +++ b/auth/src/test/java/com/alibaba/nacos/auth/config/AuthConfigsTest.java @@ -44,6 +44,7 @@ public class AuthConfigsTest { public void setUp() throws Exception { environment = new MockEnvironment(); EnvUtil.setEnvironment(environment); + environment.setProperty("nacos.core.auth.plugin.test.key", "test"); authConfigs = new AuthConfigs(); } diff --git a/console/src/main/resources/application.properties b/console/src/main/resources/application.properties index 5880d1f69..ed3054bef 100644 --- a/console/src/main/resources/application.properties +++ b/console/src/main/resources/application.properties @@ -120,16 +120,6 @@ nacos.core.auth.system.type=nacos ### If turn on auth system: nacos.core.auth.enabled=false -### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username -# nacos.core.auth.ldap.url=ldap://localhost:389 -# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com - -### The token expiration in seconds: -nacos.core.auth.default.token.expire.seconds=18000 - -### The default token: -nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 - ### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay. nacos.core.auth.caching.enabled=true @@ -141,8 +131,15 @@ nacos.core.auth.enable.userAgentAuthWhite=false nacos.core.auth.server.identity.key=serverIdentity nacos.core.auth.server.identity.value=security -### authority key in request: -nacos.core.auth.authorityKey=authority,username,password +### worked when nacos.core.auth.system.type=nacos +### The token expiration in seconds: +nacos.core.auth.plugin.nacos.token.expire.seconds=18000 +### The default token: +nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 + +### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username +# nacos.core.auth.ldap.url=ldap://localhost:389 +# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com #*************** Istio Related Configurations ***************# ### If turn on the MCP server: diff --git a/distribution/conf/application.properties b/distribution/conf/application.properties index 522d5776d..ee46edf52 100644 --- a/distribution/conf/application.properties +++ b/distribution/conf/application.properties @@ -146,16 +146,6 @@ nacos.core.auth.system.type=nacos ### If turn on auth system: nacos.core.auth.enabled=false -### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username -# nacos.core.auth.ldap.url=ldap://localhost:389 -# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com - -### The token expiration in seconds: -nacos.core.auth.default.token.expire.seconds=18000 - -### The default token: -nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 - ### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay. nacos.core.auth.caching.enabled=true @@ -167,6 +157,16 @@ nacos.core.auth.enable.userAgentAuthWhite=false nacos.core.auth.server.identity.key=serverIdentity nacos.core.auth.server.identity.value=security +### worked when nacos.core.auth.system.type=nacos +### The token expiration in seconds: +nacos.core.auth.plugin.nacos.token.expire.seconds=18000 +### The default token: +nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 + +### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username +# nacos.core.auth.ldap.url=ldap://localhost:389 +# nacos.core.auth.ldap.userdn=cn={0},ou=user,dc=company,dc=com + #*************** Istio Related Configurations ***************# ### If turn on the MCP server: nacos.istio.mcp.server.enabled=false diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/JwtTokenManager.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/JwtTokenManager.java index e382520d8..b3ed7123f 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/JwtTokenManager.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/JwtTokenManager.java @@ -16,7 +16,6 @@ package com.alibaba.nacos.plugin.auth.impl; -import com.alibaba.nacos.auth.config.AuthConfigs; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @@ -44,7 +43,7 @@ public class JwtTokenManager { private static final String AUTHORITIES_KEY = "auth"; @Autowired - private AuthConfigs authConfigs; + private NacosAuthConfig nacosAuthConfig; /** * Create token. @@ -67,11 +66,12 @@ public class JwtTokenManager { long now = System.currentTimeMillis(); Date validity; - validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L); + + validity = new Date(now + nacosAuthConfig.getTokenValidityInSeconds() * 1000L); Claims claims = Jwts.claims().setSubject(userName); return Jwts.builder().setClaims(claims).setExpiration(validity) - .signWith(Keys.hmacShaKeyFor(authConfigs.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact(); + .signWith(Keys.hmacShaKeyFor(nacosAuthConfig.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact(); } /** @@ -81,7 +81,7 @@ public class JwtTokenManager { * @return auth info */ public Authentication getAuthentication(String token) { - Claims claims = Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build() + Claims claims = Jwts.parserBuilder().setSigningKey(nacosAuthConfig.getSecretKeyBytes()).build() .parseClaimsJws(token).getBody(); List authorities = AuthorityUtils @@ -97,7 +97,7 @@ public class JwtTokenManager { * @param token token */ public void validateToken(String token) { - Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build().parseClaimsJws(token); + Jwts.parserBuilder().setSigningKey(nacosAuthConfig.getSecretKeyBytes()).build().parseClaimsJws(token); } } diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthConfig.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthConfig.java index 9d2368b19..57d0b4a58 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthConfig.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthConfig.java @@ -19,9 +19,12 @@ package com.alibaba.nacos.plugin.auth.impl; import com.alibaba.nacos.auth.config.AuthConfigs; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.core.code.ControllerMethodsCache; +import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants; import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes; import com.alibaba.nacos.plugin.auth.impl.filter.JwtAuthenticationTokenFilter; import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.io.DecodingException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; @@ -39,6 +42,8 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic import org.springframework.web.cors.CorsUtils; import javax.annotation.PostConstruct; +import java.nio.charset.StandardCharsets; +import java.util.Properties; /** * Spring security config. @@ -76,12 +81,36 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter { @Autowired private ControllerMethodsCache methodsCache; + /** + * secret key. + */ + private String secretKey; + + /** + * secret key byte array. + */ + private byte[] secretKeyBytes; + + /** + * Token validity time(seconds). + */ + private long tokenValidityInSeconds; + /** * Init. */ @PostConstruct public void init() { methodsCache.initClassMethod("com.alibaba.nacos.plugin.auth.impl.controller"); + initProperties(); + } + + private void initProperties() { + Properties properties = authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE); + String validitySeconds = properties + .getProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, AuthConstants.DEFAULT_TOKEN_EXPIRE_SECONDS); + tokenValidityInSeconds = Long.parseLong(validitySeconds); + secretKey = properties.getProperty(AuthConstants.TOKEN_SECRET_KEY, AuthConstants.DEFAULT_TOKEN_SECRET_KEY); } @Bean(name = BeanIds.AUTHENTICATION_MANAGER) @@ -141,4 +170,19 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter { return new BCryptPasswordEncoder(); } + public byte[] getSecretKeyBytes() { + if (secretKeyBytes == null) { + try { + secretKeyBytes = Decoders.BASE64.decode(secretKey); + } catch (DecodingException e) { + secretKeyBytes = secretKey.getBytes(StandardCharsets.UTF_8); + } + + } + return secretKeyBytes; + } + + public long getTokenValidityInSeconds() { + return tokenValidityInSeconds; + } } diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthPluginService.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthPluginService.java index 739224e5c..a9f55486f 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthPluginService.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthPluginService.java @@ -38,8 +38,6 @@ import java.util.List; @SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule") public class NacosAuthPluginService implements AuthPluginService { - private static final String AUTH_PLUGIN_TYPE = "nacos"; - private static final String USER_IDENTITY_PARAM_KEY = "user"; private static final List IDENTITY_NAMES = new LinkedList() { @@ -77,7 +75,7 @@ public class NacosAuthPluginService implements AuthPluginService { @Override public String getAuthServiceName() { - return AUTH_PLUGIN_TYPE; + return AuthConstants.AUTH_PLUGIN_TYPE; } private void checkNacosAuthManager() { diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java index 07e5f9ef9..4aa02d78c 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java @@ -23,6 +23,8 @@ package com.alibaba.nacos.plugin.auth.impl.constant; */ public class AuthConstants { + public static final String AUTH_PLUGIN_TYPE = "nacos"; + public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN"; public static final String AUTHORIZATION_HEADER = "Authorization"; @@ -38,4 +40,12 @@ public class AuthConstants { public static final String UPDATE_PASSWORD_ENTRY_POINT = CONSOLE_RESOURCE_NAME_PREFIX + "user/password"; public static final String NACOS_USER_KEY = "nacosuser"; + + public static final String TOKEN_SECRET_KEY = "token.secret.key"; + + public static final String DEFAULT_TOKEN_SECRET_KEY = ""; + + public static final String TOKEN_EXPIRE_SECONDS = "token.expire.seconds"; + + public static final String DEFAULT_TOKEN_EXPIRE_SECONDS = "18000"; } diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java index 14a872e36..38dc9e9c5 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java @@ -25,6 +25,7 @@ import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.plugin.auth.constant.ActionTypes; import com.alibaba.nacos.plugin.auth.exception.AccessException; import com.alibaba.nacos.plugin.auth.impl.JwtTokenManager; +import com.alibaba.nacos.plugin.auth.impl.NacosAuthConfig; import com.alibaba.nacos.plugin.auth.impl.NacosAuthManager; import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants; import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes; @@ -82,6 +83,9 @@ public class UserController { @Autowired private AuthConfigs authConfigs; + @Autowired + private NacosAuthConfig nacosAuthConfig; + @Autowired private NacosAuthManager authManager; @@ -214,7 +218,7 @@ public class UserController { ObjectNode result = JacksonUtils.createEmptyJsonNode(); result.put(Constants.ACCESS_TOKEN, user.getToken()); - result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds()); + result.put(Constants.TOKEN_TTL, nacosAuthConfig.getTokenValidityInSeconds()); result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin()); result.put(Constants.USERNAME, user.getUserName()); return result; diff --git a/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java b/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java index ac5e0a42a..209f77bf3 100644 --- a/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java +++ b/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java @@ -18,6 +18,7 @@ package com.alibaba.nacos.plugin.auth.impl.controller; import com.alibaba.nacos.auth.config.AuthConfigs; import com.alibaba.nacos.plugin.auth.exception.AccessException; +import com.alibaba.nacos.plugin.auth.impl.NacosAuthConfig; import com.alibaba.nacos.plugin.auth.impl.NacosAuthManager; import com.alibaba.nacos.plugin.auth.impl.constant.AuthSystemTypes; import com.alibaba.nacos.plugin.auth.impl.users.NacosUser; @@ -49,6 +50,9 @@ public class UserControllerTest { @Mock private AuthConfigs authConfigs; + @Mock + private NacosAuthConfig nacosAuthConfig; + @Mock private NacosAuthManager authManager; @@ -65,13 +69,14 @@ public class UserControllerTest { user.setToken("1234567890"); injectObject("authConfigs", authConfigs); injectObject("authManager", authManager); + injectObject("nacosAuthConfig", nacosAuthConfig); } @Test public void testLoginWithAuthedUser() throws AccessException { when(authManager.login(request)).thenReturn(user); when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name()); - when(authConfigs.getTokenValidityInSeconds()).thenReturn(18000L); + when(nacosAuthConfig.getTokenValidityInSeconds()).thenReturn(18000L); Object actual = userController.login("nacos", "nacos", response, request); assertThat(actual, instanceOf(JsonNode.class)); String actualString = actual.toString(); diff --git a/sys/pom.xml b/sys/pom.xml index 2222a4ae7..77882fedb 100644 --- a/sys/pom.xml +++ b/sys/pom.xml @@ -67,6 +67,10 @@ org.springframework.boot spring-boot-test + + org.codehaus.jackson + jackson-core-asl + diff --git a/sys/src/main/java/com/alibaba/nacos/sys/utils/PropertiesUtil.java b/sys/src/main/java/com/alibaba/nacos/sys/utils/PropertiesUtil.java new file mode 100644 index 000000000..f6da571dc --- /dev/null +++ b/sys/src/main/java/com/alibaba/nacos/sys/utils/PropertiesUtil.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2021 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.sys.utils; + +import org.springframework.core.env.Environment; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Properties; + +/** + * Properties util. + * + * @author xiweng.yy + */ +public class PropertiesUtil { + + public static Properties getPropertiesWithPrefix(Environment environment, String prefix) + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + return handleSpringBinder(environment, prefix, Properties.class); + } + + public static Map getPropertiesWithPrefixForMap(Environment environment, String prefix) + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + return handleSpringBinder(environment, prefix, Map.class); + } + + /** + * Handle spring binder to bind object. + * + * @param environment spring environment + * @param prefix properties prefix + * @param targetClass target class + * @param target class + * @return binder object + */ + @SuppressWarnings("unchecked") + public static T handleSpringBinder(Environment environment, String prefix, Class targetClass) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { + Class binderClass = Class.forName("org.springframework.boot.context.properties.bind.Binder"); + Method getMethod = binderClass.getDeclaredMethod("get", Environment.class); + Method bindMethod = binderClass.getDeclaredMethod("bind", String.class, Class.class); + Object binderObject = getMethod.invoke(null, environment); + String prefixParam = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix; + Object bindResultObject = bindMethod.invoke(binderObject, prefixParam, targetClass); + Method resultGetMethod = bindResultObject.getClass().getDeclaredMethod("get"); + return (T) resultGetMethod.invoke(bindResultObject); + } +} diff --git a/sys/src/test/java/com/alibaba/nacos/sys/utils/PropertiesUtilTest.java b/sys/src/test/java/com/alibaba/nacos/sys/utils/PropertiesUtilTest.java new file mode 100644 index 000000000..f0b6abbda --- /dev/null +++ b/sys/src/test/java/com/alibaba/nacos/sys/utils/PropertiesUtilTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 1999-2021 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.sys.utils; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import java.lang.reflect.InvocationTargetException; +import java.util.Map; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@ActiveProfiles("prefix") +@SpringBootTest(classes = PropertiesUtilTest.class) +public class PropertiesUtilTest { + + @Autowired + private ConfigurableEnvironment environment; + + @Test + @SuppressWarnings("unchecked") + public void testGetPropertiesWithPrefixForMap() + throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Map actual = PropertiesUtil.getPropertiesWithPrefixForMap(environment, "nacos.prefix"); + assertEquals(3, actual.size()); + for (Map.Entry entry : actual.entrySet()) { + String key = entry.getKey(); + Map subMap = (Map) entry.getValue(); + switch (key) { + case "one": + assertEquals("1", subMap.get("value")); + break; + case "two": + assertEquals("2", subMap.get("value")); + break; + case "three": + assertEquals("3", subMap.get("value")); + break; + default: + throw new RuntimeException(); + } + } + } + + @Test + public void testGetPropertiesWithPrefix() + throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Properties actual = PropertiesUtil.getPropertiesWithPrefix(environment, "nacos.prefix"); + assertEquals(3, actual.size()); + } +} diff --git a/sys/src/test/resources/application-prefix.properties b/sys/src/test/resources/application-prefix.properties new file mode 100644 index 000000000..f1c8950f2 --- /dev/null +++ b/sys/src/test/resources/application-prefix.properties @@ -0,0 +1,20 @@ +# +# Copyright 1999-2018 Alibaba Group Holding Ltd. +# +# 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. +# + +nacos.prefix.one.value=1 +nacos.prefix.two.value=2 +nacos.prefix.three.value=3 +nacos.other.prefix.one.value=1