* 1. 修复密钥编码问题--为了避免歧义,密钥必须为base64编码的字符串;不再支持原始明文密钥。 2. JwtParser是线程安全的,重构为成员变量。 * 配置项保持明文字符串
This commit is contained in:
parent
98f7066519
commit
c3c7e1ba1c
@ -127,7 +127,7 @@ 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:
|
||||
### The default token (Base64 string):
|
||||
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
|
||||
### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
|
||||
|
@ -149,7 +149,7 @@ 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:
|
||||
### The default token (Base64 String):
|
||||
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
|
||||
### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
|
||||
|
@ -16,14 +16,17 @@
|
||||
|
||||
package com.alibaba.nacos.plugin.auth.impl;
|
||||
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
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.plugin.auth.impl.constant.AuthConstants;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtParser;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.io.DecodingException;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -32,11 +35,10 @@ import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* JWT token manager.
|
||||
@ -45,43 +47,39 @@ import java.util.Properties;
|
||||
* @author nkorange
|
||||
*/
|
||||
@Component
|
||||
public class JwtTokenManager {
|
||||
public class JwtTokenManager extends Subscriber<ServerConfigChangeEvent> {
|
||||
|
||||
private static final String AUTHORITIES_KEY = "auth";
|
||||
|
||||
private final AuthConfigs authConfigs;
|
||||
|
||||
/**
|
||||
* secret key.
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* secret key byte array.
|
||||
*/
|
||||
private byte[] secretKeyBytes;
|
||||
|
||||
/**
|
||||
* Token validity time(seconds).
|
||||
*/
|
||||
private long tokenValidityInSeconds;
|
||||
|
||||
private JwtParser jwtParser;
|
||||
private volatile long tokenValidityInSeconds;
|
||||
|
||||
public JwtTokenManager(AuthConfigs authConfigs) {
|
||||
this.authConfigs = authConfigs;
|
||||
private volatile JwtParser jwtParser;
|
||||
|
||||
private volatile SecretKey secretKey;
|
||||
|
||||
public JwtTokenManager() {
|
||||
NotifyCenter.registerSubscriber(this);
|
||||
processProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* init tokenValidityInSeconds and secretKey properties.
|
||||
*/
|
||||
@PostConstruct
|
||||
public 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);
|
||||
private void processProperties() {
|
||||
this.tokenValidityInSeconds = EnvUtil.getProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, Long.class,
|
||||
AuthConstants.DEFAULT_TOKEN_EXPIRE_SECONDS);
|
||||
|
||||
String encodedSecretKey = EnvUtil.getProperty(AuthConstants.TOKEN_SECRET_KEY,
|
||||
AuthConstants.DEFAULT_TOKEN_SECRET_KEY);
|
||||
try {
|
||||
this.secretKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(encodedSecretKey));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"the length of must great than or equal 32 bytes; And the secret key must be encoded by base64",
|
||||
e);
|
||||
}
|
||||
|
||||
this.jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,15 +100,12 @@ public class JwtTokenManager {
|
||||
*/
|
||||
public String createToken(String userName) {
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Date validity;
|
||||
|
||||
validity = new Date(now + this.getTokenValidityInSeconds() * 1000L);
|
||||
Date validity = new Date(
|
||||
System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(this.getTokenValidityInSeconds()));
|
||||
|
||||
Claims claims = Jwts.claims().setSubject(userName);
|
||||
return Jwts.builder().setClaims(claims).setExpiration(validity)
|
||||
.signWith(Keys.hmacShaKeyFor(this.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact();
|
||||
return Jwts.builder().setClaims(claims).setExpiration(validity).signWith(secretKey, SignatureAlgorithm.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,13 +115,10 @@ public class JwtTokenManager {
|
||||
* @return auth info
|
||||
*/
|
||||
public Authentication getAuthentication(String token) {
|
||||
if (jwtParser == null) {
|
||||
jwtParser = Jwts.parserBuilder().setSigningKey(this.getSecretKeyBytes()).build();
|
||||
}
|
||||
Claims claims = jwtParser.parseClaimsJws(token).getBody();
|
||||
|
||||
List<GrantedAuthority> authorities = AuthorityUtils
|
||||
.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
|
||||
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(
|
||||
(String) claims.get(AUTHORITIES_KEY));
|
||||
|
||||
User principal = new User(claims.getSubject(), "", authorities);
|
||||
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
|
||||
@ -138,25 +130,20 @@ public class JwtTokenManager {
|
||||
* @param token token
|
||||
*/
|
||||
public void validateToken(String token) {
|
||||
if (jwtParser == null) {
|
||||
jwtParser = Jwts.parserBuilder().setSigningKey(this.getSecretKeyBytes()).build();
|
||||
}
|
||||
jwtParser.parseClaimsJws(token);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(ServerConfigChangeEvent event) {
|
||||
processProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Event> subscribeType() {
|
||||
return ServerConfigChangeEvent.class;
|
||||
}
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ public class AuthConstants {
|
||||
|
||||
public static final String NACOS_USER_KEY = "nacosuser";
|
||||
|
||||
public static final String TOKEN_SECRET_KEY = "token.secret.key";
|
||||
public static final String TOKEN_SECRET_KEY = "nacos.core.auth.plugin.nacos.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 TOKEN_EXPIRE_SECONDS = "nacos.core.auth.plugin.nacos.token.expire.seconds";
|
||||
|
||||
public static final String DEFAULT_TOKEN_EXPIRE_SECONDS = "18000";
|
||||
public static final Long DEFAULT_TOKEN_EXPIRE_SECONDS = 18_000L;
|
||||
|
||||
public static final String NACOS_CORE_AUTH_LDAP_URL = "nacos.core.auth.ldap.url";
|
||||
|
||||
|
@ -16,72 +16,72 @@
|
||||
|
||||
package com.alibaba.nacos.plugin.auth.impl;
|
||||
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
|
||||
import io.jsonwebtoken.lang.Assert;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import io.jsonwebtoken.io.Encoders;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class JwtTokenManagerTest {
|
||||
|
||||
@Mock
|
||||
private AuthConfigs authConfigs;
|
||||
|
||||
private JwtTokenManager jwtTokenManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(AuthConstants.TOKEN_SECRET_KEY,
|
||||
"SecretKey0123$567890$234567890123456789012345678901234567890123456789");
|
||||
properties.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, "300");
|
||||
when(authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE)).thenReturn(properties);
|
||||
jwtTokenManager = new JwtTokenManager(authConfigs);
|
||||
jwtTokenManager.initProperties();
|
||||
MockEnvironment mockEnvironment = new MockEnvironment();
|
||||
mockEnvironment.setProperty(AuthConstants.TOKEN_SECRET_KEY, Encoders.BASE64.encode(
|
||||
"SecretKey0123$567890$234567890123456789012345678901234567890123456789".getBytes(
|
||||
StandardCharsets.UTF_8)));
|
||||
mockEnvironment.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS,
|
||||
AuthConstants.DEFAULT_TOKEN_EXPIRE_SECONDS.toString());
|
||||
|
||||
EnvUtil.setEnvironment(mockEnvironment);
|
||||
|
||||
jwtTokenManager = new JwtTokenManager();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTokenAndSecretKeyWithoutSpecialSymbol() throws NoSuchFieldException, IllegalAccessException {
|
||||
createToken("SecretKey0123$567890$234567890123456789012345678901234567890123456789");
|
||||
public void testCreateTokenAndSecretKeyWithoutSpecialSymbol() {
|
||||
createToken("SecretKey0123567890234567890123456789012345678901234567890123456789");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTokenAndSecretKeyWithSpecialSymbol() throws NoSuchFieldException, IllegalAccessException {
|
||||
createToken("SecretKey012345678901234567890123456789012345678901234567890123456789");
|
||||
public void testCreateTokenAndSecretKeyWithSpecialSymbol() {
|
||||
createToken("SecretKey01234@#!5678901234567890123456789012345678901234567890123456789");
|
||||
}
|
||||
|
||||
private void createToken(String secretKey) throws NoSuchFieldException, IllegalAccessException {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(AuthConstants.TOKEN_SECRET_KEY, secretKey);
|
||||
properties.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, "300");
|
||||
when(authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE)).thenReturn(properties);
|
||||
JwtTokenManager jwtTokenManager = new JwtTokenManager(authConfigs);
|
||||
jwtTokenManager.initProperties();
|
||||
private void createToken(String secretKey) {
|
||||
MockEnvironment mockEnvironment = new MockEnvironment();
|
||||
mockEnvironment.setProperty(AuthConstants.TOKEN_SECRET_KEY,
|
||||
Encoders.BASE64.encode(secretKey.getBytes(StandardCharsets.UTF_8)));
|
||||
mockEnvironment.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS,
|
||||
AuthConstants.DEFAULT_TOKEN_EXPIRE_SECONDS.toString());
|
||||
|
||||
EnvUtil.setEnvironment(mockEnvironment);
|
||||
|
||||
JwtTokenManager jwtTokenManager = new JwtTokenManager();
|
||||
String nacosToken = jwtTokenManager.createToken("nacos");
|
||||
Assert.notNull(nacosToken);
|
||||
Assert.assertNotNull(nacosToken);
|
||||
jwtTokenManager.validateToken(nacosToken);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAuthentication() throws NoSuchFieldException, IllegalAccessException {
|
||||
public void getAuthentication() {
|
||||
String nacosToken = jwtTokenManager.createToken("nacos");
|
||||
Authentication authentication = jwtTokenManager.getAuthentication(nacosToken);
|
||||
org.junit.Assert.assertNotNull(authentication);
|
||||
Assert.assertNotNull(authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSecretKeyBytes() {
|
||||
byte[] secretKeyBytes = jwtTokenManager.getSecretKeyBytes();
|
||||
org.junit.Assert.assertNotNull(secretKeyBytes);
|
||||
public void testInvalidSecretKey() {
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> createToken("0123456789ABCDEF0123456789ABCDE"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,23 +23,24 @@ 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;
|
||||
import com.alibaba.nacos.plugin.auth.impl.users.NacosUser;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import io.jsonwebtoken.io.Encoders;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Properties;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@ -76,12 +77,16 @@ public class UserControllerTest {
|
||||
user.setToken("1234567890");
|
||||
injectObject("authConfigs", authConfigs);
|
||||
injectObject("authManager", authManager);
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(AuthConstants.TOKEN_SECRET_KEY, "SecretKey012345678901234567890123456789012345678901234567890123456789");
|
||||
properties.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS, "300");
|
||||
when(authConfigs.getAuthPluginProperties(AuthConstants.AUTH_PLUGIN_TYPE)).thenReturn(properties);
|
||||
JwtTokenManager jwtTokenManager = new JwtTokenManager(authConfigs);
|
||||
jwtTokenManager.initProperties();
|
||||
|
||||
MockEnvironment mockEnvironment = new MockEnvironment();
|
||||
mockEnvironment.setProperty(AuthConstants.TOKEN_SECRET_KEY, Encoders.BASE64.encode(
|
||||
"SecretKey0123$567890$234567890123456789012345678901234567890123456789".getBytes(
|
||||
StandardCharsets.UTF_8)));
|
||||
mockEnvironment.setProperty(AuthConstants.TOKEN_EXPIRE_SECONDS,
|
||||
AuthConstants.DEFAULT_TOKEN_EXPIRE_SECONDS.toString());
|
||||
|
||||
EnvUtil.setEnvironment(mockEnvironment);
|
||||
JwtTokenManager jwtTokenManager = new JwtTokenManager();
|
||||
injectObject("jwtTokenManager", jwtTokenManager);
|
||||
}
|
||||
|
||||
@ -89,12 +94,11 @@ public class UserControllerTest {
|
||||
public void testLoginWithAuthedUser() throws AccessException {
|
||||
when(authManager.login(request)).thenReturn(user);
|
||||
when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name());
|
||||
when(jwtTokenManager.getTokenValidityInSeconds()).thenReturn(18000L);
|
||||
Object actual = userController.login("nacos", "nacos", response, request);
|
||||
assertThat(actual, instanceOf(JsonNode.class));
|
||||
assertTrue(actual instanceof JsonNode);
|
||||
String actualString = actual.toString();
|
||||
assertTrue(actualString.contains("\"accessToken\":\"1234567890\""));
|
||||
assertTrue(actualString.contains("\"tokenTtl\":300"));
|
||||
assertTrue(actualString.contains("\"tokenTtl\":18000"));
|
||||
assertTrue(actualString.contains("\"globalAdmin\":true"));
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ nacos.core.auth.caching.enabled=false
|
||||
nacos.core.auth.default.token.expire.seconds=18000
|
||||
|
||||
### The default token:
|
||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
#nacos.core.auth.default.token.secret.key=U2VjcmV0S2V5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
|
||||
nacos.core.auth.plugin.nacos.token.secret.key=U2VjcmV0S2V5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
|
||||
|
||||
tldSkipPatterns=derbyLocale_*.jar,jaxb-api.jar,jsr173_1.0_api.jar,jaxb1-impl.jar,activation.jar
|
||||
|
@ -50,6 +50,6 @@ nacos.core.auth.caching.enabled=false
|
||||
nacos.core.auth.default.token.expire.seconds=18000
|
||||
|
||||
### The default token:
|
||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
nacos.core.auth.plugin.nacos.token.secret.key=${nacos.core.auth.default.token.secret.key}
|
||||
#nacos.core.auth.default.token.secret.key=U2VjcmV0S2V5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
|
||||
nacos.core.auth.plugin.nacos.token.secret.key=U2VjcmV0S2V5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
|
||||
tldSkipPatterns=derbyLocale_*.jar,jaxb-api.jar,jsr173_1.0_api.jar,jaxb1-impl.jar,activation.jar
|
||||
|
@ -411,7 +411,9 @@ public class MultiTenant_InstanceAPI_ITCase {
|
||||
.appendParam("namespaceId", "namespace-1").appendParam("groupName", TEST_GROUP_1).done(),
|
||||
String.class);
|
||||
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||
JsonNode json = JacksonUtils.toObj(response.getBody());
|
||||
String body = response.getBody();
|
||||
System.out.println("multipleTenant_group_updateInstance_notExsitInstance received body: " + body);
|
||||
JsonNode json = JacksonUtils.toObj(body);
|
||||
Assert.assertEquals("33.33.33.33", json.get("hosts").get(0).get("ip").asText());
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,8 @@ nacos.core.auth.caching.enabled=false
|
||||
### The token expiration in seconds:
|
||||
nacos.core.auth.default.token.expire.seconds=18000
|
||||
|
||||
### The default token:
|
||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
### The default token (Base64 String):
|
||||
#nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
|
||||
tldSkipPatterns=derbyLocale_*.jar,jaxb-api.jar,jsr173_1.0_api.jar,jaxb1-impl.jar,activation.jar
|
||||
|
Loading…
Reference in New Issue
Block a user