[ISSUE#10062] Naming support aliyun STS auth. (#10063)

* Naming support aliyun STS auth.

* Add UT for sts auth.

* Fix UT stability.
This commit is contained in:
杨翊 SionYang 2023-03-10 09:18:41 +08:00 committed by GitHub
parent 02a5e38981
commit 383287c616
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 419 additions and 76 deletions

View File

@ -27,6 +27,8 @@ public class IdentifyConstants {
public static final String SECRET_KEY = "secretKey"; public static final String SECRET_KEY = "secretKey";
public static final String SECURITY_TOKEN_HEADER = "Spas-SecurityToken";
public static final String TENANT_ID = "tenantId"; public static final String TENANT_ID = "tenantId";
public static final String PROPERTIES_FILENAME = "spas.properties"; public static final String PROPERTIES_FILENAME = "spas.properties";

View File

@ -0,0 +1,98 @@
/*
* 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.client.auth.ram.identify;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.client.config.impl.ConfigHttpClientManager;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.Query;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import org.slf4j.Logger;
/**
* Sts credential holder.
*
* @author xiweng.yy
*/
public class StsCredentialHolder {
private static final Logger LOGGER = LogUtils.logger(StsCredentialHolder.class);
private static final StsCredentialHolder INSTANCE = new StsCredentialHolder();
private StsCredential stsCredential;
private StsCredentialHolder() {
}
public static StsCredentialHolder getInstance() {
return INSTANCE;
}
/**
* Get Sts Credential.
*
* @return StsCredential
*/
public StsCredential getStsCredential() {
boolean cacheSecurityCredentials = StsConfig.getInstance().isCacheSecurityCredentials();
if (cacheSecurityCredentials && stsCredential != null) {
long currentTime = System.currentTimeMillis();
long expirationTime = stsCredential.getExpiration().getTime();
int timeToRefreshInMillisecond = StsConfig.getInstance().getTimeToRefreshInMillisecond();
if (expirationTime - currentTime > timeToRefreshInMillisecond) {
return stsCredential;
}
}
String stsResponse = getStsResponse();
stsCredential = JacksonUtils.toObj(stsResponse, new TypeReference<StsCredential>() {
});
LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}",
stsCredential.getCode(), stsCredential.getAccessKeyId(), stsCredential.getLastUpdated(),
stsCredential.getExpiration());
return stsCredential;
}
private static String getStsResponse() {
String securityCredentials = StsConfig.getInstance().getSecurityCredentials();
if (securityCredentials != null) {
return securityCredentials;
}
String securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl();
try {
HttpRestResult<String> result = ConfigHttpClientManager.getInstance().getNacosRestTemplate()
.get(securityCredentialsUrl, Header.EMPTY, Query.EMPTY, String.class);
if (!result.ok()) {
LOGGER.error(
"can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}",
securityCredentialsUrl, result.getCode(), result.getMessage());
throw new NacosRuntimeException(NacosException.SERVER_ERROR,
"can not get security credentials, responseCode: " + result.getCode() + ", response: " + result
.getMessage());
}
return result.getData();
} catch (Exception e) {
LOGGER.error("can not get security credentials", e);
throw new NacosRuntimeException(NacosException.SERVER_ERROR, e);
}
}
}

View File

@ -16,23 +16,15 @@
package com.alibaba.nacos.client.auth.ram.injector; package com.alibaba.nacos.client.auth.ram.injector;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext;
import com.alibaba.nacos.client.auth.ram.RamContext; import com.alibaba.nacos.client.auth.ram.RamContext;
import com.alibaba.nacos.plugin.auth.api.RequestResource; import com.alibaba.nacos.client.auth.ram.identify.IdentifyConstants;
import com.alibaba.nacos.client.config.impl.ConfigHttpClientManager;
import com.alibaba.nacos.client.auth.ram.utils.SpasAdapter;
import com.alibaba.nacos.client.auth.ram.identify.StsConfig; import com.alibaba.nacos.client.auth.ram.identify.StsConfig;
import com.alibaba.nacos.client.auth.ram.identify.StsCredential; import com.alibaba.nacos.client.auth.ram.identify.StsCredential;
import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.auth.ram.identify.StsCredentialHolder;
import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.client.auth.ram.utils.SpasAdapter;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.Query;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.common.utils.StringUtils;
import com.fasterxml.jackson.core.type.TypeReference; import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext;
import org.slf4j.Logger; import com.alibaba.nacos.plugin.auth.api.RequestResource;
import java.util.Map; import java.util.Map;
@ -43,26 +35,20 @@ import java.util.Map;
*/ */
public class ConfigResourceInjector extends AbstractResourceInjector { public class ConfigResourceInjector extends AbstractResourceInjector {
private static final Logger LOGGER = LogUtils.logger(ConfigResourceInjector.class);
private static final String SECURITY_TOKEN_HEADER = "Spas-SecurityToken";
private static final String ACCESS_KEY_HEADER = "Spas-AccessKey"; private static final String ACCESS_KEY_HEADER = "Spas-AccessKey";
private static final String DEFAULT_RESOURCE = ""; private static final String DEFAULT_RESOURCE = "";
private StsCredential stsCredential;
@Override @Override
public void doInject(RequestResource resource, RamContext context, LoginIdentityContext result) { public void doInject(RequestResource resource, RamContext context, LoginIdentityContext result) {
String accessKey = context.getAccessKey(); String accessKey = context.getAccessKey();
String secretKey = context.getSecretKey(); String secretKey = context.getSecretKey();
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权 // STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
if (StsConfig.getInstance().isStsOn()) { if (StsConfig.getInstance().isStsOn()) {
StsCredential stsCredential = getStsCredential(); StsCredential stsCredential = StsCredentialHolder.getInstance().getStsCredential();
accessKey = stsCredential.getAccessKeyId(); accessKey = stsCredential.getAccessKeyId();
secretKey = stsCredential.getAccessKeySecret(); secretKey = stsCredential.getAccessKeySecret();
result.setParameter(SECURITY_TOKEN_HEADER, stsCredential.getSecurityToken()); result.setParameter(IdentifyConstants.SECURITY_TOKEN_HEADER, stsCredential.getSecurityToken());
} }
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotBlank(secretKey)) { if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotBlank(secretKey)) {
@ -73,50 +59,6 @@ public class ConfigResourceInjector extends AbstractResourceInjector {
result.setParameters(signHeaders); result.setParameters(signHeaders);
} }
private StsCredential getStsCredential() {
boolean cacheSecurityCredentials = StsConfig.getInstance().isCacheSecurityCredentials();
if (cacheSecurityCredentials && stsCredential != null) {
long currentTime = System.currentTimeMillis();
long expirationTime = stsCredential.getExpiration().getTime();
int timeToRefreshInMillisecond = StsConfig.getInstance().getTimeToRefreshInMillisecond();
if (expirationTime - currentTime > timeToRefreshInMillisecond) {
return stsCredential;
}
}
String stsResponse = getStsResponse();
stsCredential = JacksonUtils.toObj(stsResponse, new TypeReference<StsCredential>() {
});
LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}",
stsCredential.getCode(), stsCredential.getAccessKeyId(), stsCredential.getLastUpdated(),
stsCredential.getExpiration());
return stsCredential;
}
private static String getStsResponse() {
String securityCredentials = StsConfig.getInstance().getSecurityCredentials();
if (securityCredentials != null) {
return securityCredentials;
}
String securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl();
try {
HttpRestResult<String> result = ConfigHttpClientManager.getInstance().getNacosRestTemplate()
.get(securityCredentialsUrl, Header.EMPTY, Query.EMPTY, String.class);
if (!result.ok()) {
LOGGER.error(
"can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}",
securityCredentialsUrl, result.getCode(), result.getMessage());
throw new NacosRuntimeException(NacosException.SERVER_ERROR,
"can not get security credentials, responseCode: " + result.getCode() + ", response: " + result
.getMessage());
}
return result.getData();
} catch (Exception e) {
LOGGER.error("can not get security credentials", e);
throw new NacosRuntimeException(NacosException.SERVER_ERROR, e);
}
}
private String getResource(String tenant, String group) { private String getResource(String tenant, String group) {
if (StringUtils.isNotBlank(tenant) && StringUtils.isNotBlank(group)) { if (StringUtils.isNotBlank(tenant) && StringUtils.isNotBlank(group)) {
return tenant + "+" + group; return tenant + "+" + group;

View File

@ -18,6 +18,10 @@ package com.alibaba.nacos.client.auth.ram.injector;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.utils.NamingUtils; import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.client.auth.ram.identify.IdentifyConstants;
import com.alibaba.nacos.client.auth.ram.identify.StsConfig;
import com.alibaba.nacos.client.auth.ram.identify.StsCredential;
import com.alibaba.nacos.client.auth.ram.identify.StsCredentialHolder;
import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext; import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext;
import com.alibaba.nacos.client.auth.ram.RamContext; import com.alibaba.nacos.client.auth.ram.RamContext;
import com.alibaba.nacos.plugin.auth.api.RequestResource; import com.alibaba.nacos.plugin.auth.api.RequestResource;
@ -43,11 +47,20 @@ public class NamingResourceInjector extends AbstractResourceInjector {
public void doInject(RequestResource resource, RamContext context, LoginIdentityContext result) { public void doInject(RequestResource resource, RamContext context, LoginIdentityContext result) {
if (context.validate()) { if (context.validate()) {
try { try {
String accessKey = context.getAccessKey();
String secretKey = context.getSecretKey();
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
if (StsConfig.getInstance().isStsOn()) {
StsCredential stsCredential = StsCredentialHolder.getInstance().getStsCredential();
accessKey = stsCredential.getAccessKeyId();
secretKey = stsCredential.getAccessKeySecret();
result.setParameter(IdentifyConstants.SECURITY_TOKEN_HEADER, stsCredential.getSecurityToken());
}
String signData = getSignData(getGroupedServiceName(resource)); String signData = getSignData(getGroupedServiceName(resource));
String signature = SignUtil.sign(signData, context.getSecretKey()); String signature = SignUtil.sign(signData, secretKey);
result.setParameter(SIGNATURE_FILED, signature); result.setParameter(SIGNATURE_FILED, signature);
result.setParameter(DATA_FILED, signData); result.setParameter(DATA_FILED, signData);
result.setParameter(AK_FILED, context.getAccessKey()); result.setParameter(AK_FILED, accessKey);
} catch (Exception e) { } catch (Exception e) {
NAMING_LOGGER.error("inject ak/sk failed.", e); NAMING_LOGGER.error("inject ak/sk failed.", e);
} }

View File

@ -0,0 +1,134 @@
/*
* 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.client.auth.ram.identify;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.client.config.impl.ConfigHttpClientManager;
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
import com.alibaba.nacos.common.http.client.request.HttpClientRequest;
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Field;
import java.util.Date;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class StsCredentialHolderTest {
private String securityCredentialsUrl;
private HttpClientRequest httpClient;
@Mock
private HttpClientRequest mockRest;
@Before
public void setUp() throws Exception {
securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl();
StsConfig.getInstance().setSecurityCredentialsUrl("url");
Field field = NacosRestTemplate.class.getDeclaredField("requestClient");
field.setAccessible(true);
httpClient = (HttpClientRequest) field.get(ConfigHttpClientManager.getInstance().getNacosRestTemplate());
field.set(ConfigHttpClientManager.getInstance().getNacosRestTemplate(), mockRest);
}
@After
public void tearDown() throws Exception {
StsConfig.getInstance().setSecurityCredentials(null);
StsConfig.getInstance().setSecurityCredentialsUrl(securityCredentialsUrl);
Field field = NacosRestTemplate.class.getDeclaredField("requestClient");
field.setAccessible(true);
field.set(ConfigHttpClientManager.getInstance().getNacosRestTemplate(), httpClient);
clearForSts();
}
private void clearForSts() throws NoSuchFieldException, IllegalAccessException {
StsConfig.getInstance().setSecurityCredentialsUrl(null);
Field field = StsCredentialHolder.class.getDeclaredField("stsCredential");
field.setAccessible(true);
field.set(StsCredentialHolder.getInstance(), null);
}
@Test
public void testGetStsCredentialFromCache() throws NoSuchFieldException, IllegalAccessException {
StsCredential stsCredential = buildMockStsCredential();
setStsCredential(stsCredential);
assertEquals(stsCredential, StsCredentialHolder.getInstance().getStsCredential());
}
private void setStsCredential(StsCredential stsCredential) throws NoSuchFieldException, IllegalAccessException {
Field field = StsCredentialHolder.class.getDeclaredField("stsCredential");
field.setAccessible(true);
field.set(StsCredentialHolder.getInstance(), stsCredential);
}
@Test
public void testGetStsCredentialFromStringCache() throws NoSuchFieldException, IllegalAccessException {
StsCredential stsCredential = buildMockStsCredential();
StsConfig.getInstance().setSecurityCredentials(JacksonUtils.toJson(stsCredential));
assertEquals(stsCredential.toString(), StsCredentialHolder.getInstance().getStsCredential().toString());
}
@Test
public void testGetStsCredentialFromRequest() throws Exception {
StsCredential stsCredential = buildMockStsCredential();
HttpClientResponse response = mock(HttpClientResponse.class);
when(response.getStatusCode()).thenReturn(200);
when(response.getHeaders()).thenReturn(Header.newInstance());
when(response.getBody()).thenReturn(new ByteArrayInputStream(JacksonUtils.toJsonBytes(stsCredential)));
when(mockRest.execute(any(), any(), any())).thenReturn(response);
assertEquals(stsCredential.toString(), StsCredentialHolder.getInstance().getStsCredential().toString());
}
@Test(expected = NacosRuntimeException.class)
public void testGetStsCredentialFromRequestFailure() throws Exception {
HttpClientResponse response = mock(HttpClientResponse.class);
when(response.getStatusCode()).thenReturn(500);
when(response.getHeaders()).thenReturn(Header.newInstance());
when(response.getBody()).thenReturn(new ByteArrayInputStream(new byte[0]));
when(mockRest.execute(any(), any(), any())).thenReturn(response);
StsCredentialHolder.getInstance().getStsCredential();
}
@Test(expected = NacosRuntimeException.class)
public void testGetStsCredentialFromRequestException() throws Exception {
when(mockRest.execute(any(), any(), any())).thenThrow(new RuntimeException("test"));
StsCredentialHolder.getInstance().getStsCredential();
}
private StsCredential buildMockStsCredential() {
StsCredential stsCredential = new StsCredential();
stsCredential.setAccessKeyId("test-sts-ak");
stsCredential.setAccessKeySecret("test-sts-sk");
stsCredential.setSecurityToken("test-sts-token");
stsCredential.setExpiration(new Date(System.currentTimeMillis() + 1000000));
return stsCredential;
}
}

View File

@ -17,16 +17,22 @@
package com.alibaba.nacos.client.auth.ram.injector; package com.alibaba.nacos.client.auth.ram.injector;
import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext;
import com.alibaba.nacos.client.auth.ram.RamContext; import com.alibaba.nacos.client.auth.ram.RamContext;
import com.alibaba.nacos.plugin.auth.api.RequestResource; import com.alibaba.nacos.client.auth.ram.identify.IdentifyConstants;
import com.alibaba.nacos.client.auth.ram.identify.StsConfig; import com.alibaba.nacos.client.auth.ram.identify.StsConfig;
import com.alibaba.nacos.client.auth.ram.identify.StsCredential;
import com.alibaba.nacos.client.auth.ram.identify.StsCredentialHolder;
import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext;
import com.alibaba.nacos.plugin.auth.api.RequestResource;
import com.alibaba.nacos.plugin.auth.constant.SignType; import com.alibaba.nacos.plugin.auth.constant.SignType;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.Field;
import java.util.Date;
public class ConfigResourceInjectorTest { public class ConfigResourceInjectorTest {
private ConfigResourceInjector configResourceInjector; private ConfigResourceInjector configResourceInjector;
@ -39,6 +45,8 @@ public class ConfigResourceInjectorTest {
private String cachedSecurityCredentials; private String cachedSecurityCredentials;
private StsCredential stsCredential;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
configResourceInjector = new ConfigResourceInjector(); configResourceInjector = new ConfigResourceInjector();
@ -53,16 +61,18 @@ public class ConfigResourceInjectorTest {
cachedSecurityCredentials = StsConfig.getInstance().getSecurityCredentials(); cachedSecurityCredentials = StsConfig.getInstance().getSecurityCredentials();
StsConfig.getInstance().setSecurityCredentialsUrl(""); StsConfig.getInstance().setSecurityCredentialsUrl("");
StsConfig.getInstance().setSecurityCredentials(""); StsConfig.getInstance().setSecurityCredentials("");
stsCredential = new StsCredential();
} }
@After @After
public void tearDown() { public void tearDown() throws NoSuchFieldException, IllegalAccessException {
StsConfig.getInstance().setSecurityCredentialsUrl(cachedSecurityCredentialsUrl); StsConfig.getInstance().setSecurityCredentialsUrl(cachedSecurityCredentialsUrl);
StsConfig.getInstance().setSecurityCredentials(cachedSecurityCredentials); StsConfig.getInstance().setSecurityCredentials(cachedSecurityCredentials);
clearForSts();
} }
@Test @Test
public void testDoInject() throws Exception { public void testDoInjectWithFullResource() throws Exception {
LoginIdentityContext actual = new LoginIdentityContext(); LoginIdentityContext actual = new LoginIdentityContext();
configResourceInjector.doInject(resource, ramContext, actual); configResourceInjector.doInject(resource, ramContext, actual);
Assert.assertEquals(3, actual.getAllKey().size()); Assert.assertEquals(3, actual.getAllKey().size());
@ -70,4 +80,67 @@ public class ConfigResourceInjectorTest {
Assert.assertTrue(actual.getAllKey().contains("Timestamp")); Assert.assertTrue(actual.getAllKey().contains("Timestamp"));
Assert.assertTrue(actual.getAllKey().contains("Spas-Signature")); Assert.assertTrue(actual.getAllKey().contains("Spas-Signature"));
} }
@Test
public void testDoInjectWithTenant() throws Exception {
resource.setGroup("");
LoginIdentityContext actual = new LoginIdentityContext();
configResourceInjector.doInject(resource, ramContext, actual);
Assert.assertEquals(3, actual.getAllKey().size());
Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("Spas-AccessKey"));
Assert.assertTrue(actual.getAllKey().contains("Timestamp"));
Assert.assertTrue(actual.getAllKey().contains("Spas-Signature"));
}
@Test
public void testDoInjectWithGroup() throws Exception {
resource.setNamespace("");
LoginIdentityContext actual = new LoginIdentityContext();
configResourceInjector.doInject(resource, ramContext, actual);
Assert.assertEquals(3, actual.getAllKey().size());
Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("Spas-AccessKey"));
Assert.assertTrue(actual.getAllKey().contains("Timestamp"));
Assert.assertTrue(actual.getAllKey().contains("Spas-Signature"));
}
@Test
public void testDoInjectWithoutResource() throws Exception {
resource = new RequestResource();
LoginIdentityContext actual = new LoginIdentityContext();
configResourceInjector.doInject(resource, ramContext, actual);
Assert.assertEquals(3, actual.getAllKey().size());
Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("Spas-AccessKey"));
Assert.assertTrue(actual.getAllKey().contains("Timestamp"));
Assert.assertTrue(actual.getAllKey().contains("Spas-Signature"));
}
@Test
public void testDoInjectForSts() throws NoSuchFieldException, IllegalAccessException {
prepareForSts();
LoginIdentityContext actual = new LoginIdentityContext();
configResourceInjector.doInject(resource, ramContext, actual);
Assert.assertEquals(4, actual.getAllKey().size());
Assert.assertEquals("test-sts-ak", actual.getParameter("Spas-AccessKey"));
Assert.assertTrue(actual.getAllKey().contains("Timestamp"));
Assert.assertTrue(actual.getAllKey().contains("Spas-Signature"));
Assert.assertTrue(actual.getAllKey().contains(IdentifyConstants.SECURITY_TOKEN_HEADER));
}
private void prepareForSts() throws NoSuchFieldException, IllegalAccessException {
StsConfig.getInstance().setSecurityCredentialsUrl("test");
Field field = StsCredentialHolder.class.getDeclaredField("stsCredential");
field.setAccessible(true);
field.set(StsCredentialHolder.getInstance(), stsCredential);
stsCredential.setAccessKeyId("test-sts-ak");
stsCredential.setAccessKeySecret("test-sts-sk");
stsCredential.setSecurityToken("test-sts-token");
stsCredential.setExpiration(new Date(System.currentTimeMillis() + 1000000));
}
private void clearForSts() throws NoSuchFieldException, IllegalAccessException {
StsConfig.getInstance().setSecurityCredentialsUrl(null);
Field field = StsCredentialHolder.class.getDeclaredField("stsCredential");
field.setAccessible(true);
field.set(StsCredentialHolder.getInstance(), null);
}
} }

View File

@ -17,14 +17,21 @@
package com.alibaba.nacos.client.auth.ram.injector; package com.alibaba.nacos.client.auth.ram.injector;
import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext;
import com.alibaba.nacos.client.auth.ram.RamContext; import com.alibaba.nacos.client.auth.ram.RamContext;
import com.alibaba.nacos.plugin.auth.api.RequestResource; import com.alibaba.nacos.client.auth.ram.identify.StsConfig;
import com.alibaba.nacos.client.auth.ram.identify.StsCredential;
import com.alibaba.nacos.client.auth.ram.identify.StsCredentialHolder;
import com.alibaba.nacos.client.auth.ram.utils.SignUtil; import com.alibaba.nacos.client.auth.ram.utils.SignUtil;
import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext;
import com.alibaba.nacos.plugin.auth.api.RequestResource;
import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.Field;
import java.util.Date;
public class NamingResourceInjectorTest { public class NamingResourceInjectorTest {
private NamingResourceInjector namingResourceInjector; private NamingResourceInjector namingResourceInjector;
@ -33,12 +40,32 @@ public class NamingResourceInjectorTest {
private RequestResource resource; private RequestResource resource;
private StsCredential stsCredential;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
namingResourceInjector = new NamingResourceInjector(); namingResourceInjector = new NamingResourceInjector();
ramContext = new RamContext(); ramContext = new RamContext();
ramContext.setAccessKey(PropertyKeyConst.ACCESS_KEY); ramContext.setAccessKey(PropertyKeyConst.ACCESS_KEY);
ramContext.setSecretKey(PropertyKeyConst.SECRET_KEY); ramContext.setSecretKey(PropertyKeyConst.SECRET_KEY);
stsCredential = new StsCredential();
}
@After
public void tearDown() throws NoSuchFieldException, IllegalAccessException {
clearForSts();
}
@Test
public void testDoInjectWithEmpty() throws Exception {
resource = RequestResource.namingBuilder().setResource("").build();
LoginIdentityContext actual = new LoginIdentityContext();
namingResourceInjector.doInject(resource, ramContext, actual);
String expectSign = SignUtil.sign(actual.getParameter("data"), PropertyKeyConst.SECRET_KEY);
Assert.assertEquals(3, actual.getAllKey().size());
Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("ak"));
Assert.assertTrue(Long.parseLong(actual.getParameter("data")) - System.currentTimeMillis() < 100);
Assert.assertEquals(expectSign, actual.getParameter("signature"));
} }
@Test @Test
@ -46,10 +73,10 @@ public class NamingResourceInjectorTest {
resource = RequestResource.namingBuilder().setResource("test@@aaa").setGroup("group").build(); resource = RequestResource.namingBuilder().setResource("test@@aaa").setGroup("group").build();
LoginIdentityContext actual = new LoginIdentityContext(); LoginIdentityContext actual = new LoginIdentityContext();
namingResourceInjector.doInject(resource, ramContext, actual); namingResourceInjector.doInject(resource, ramContext, actual);
String expectSign = SignUtil.sign(actual.getParameter("data"), PropertyKeyConst.SECRET_KEY);
Assert.assertEquals(3, actual.getAllKey().size()); Assert.assertEquals(3, actual.getAllKey().size());
Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("ak")); Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("ak"));
Assert.assertTrue(actual.getParameter("data").endsWith("@@test@@aaa")); Assert.assertTrue(actual.getParameter("data").endsWith("@@test@@aaa"));
String expectSign = SignUtil.sign(actual.getParameter("data"), PropertyKeyConst.SECRET_KEY);
Assert.assertEquals(expectSign, actual.getParameter("signature")); Assert.assertEquals(expectSign, actual.getParameter("signature"));
} }
@ -58,10 +85,64 @@ public class NamingResourceInjectorTest {
resource = RequestResource.namingBuilder().setResource("aaa").setGroup("group").build(); resource = RequestResource.namingBuilder().setResource("aaa").setGroup("group").build();
LoginIdentityContext actual = new LoginIdentityContext(); LoginIdentityContext actual = new LoginIdentityContext();
namingResourceInjector.doInject(resource, ramContext, actual); namingResourceInjector.doInject(resource, ramContext, actual);
Assert.assertTrue(actual.getParameter("data").endsWith("@@group@@aaa"));
Assert.assertEquals(3, actual.getAllKey().size()); Assert.assertEquals(3, actual.getAllKey().size());
Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("ak")); Assert.assertEquals(PropertyKeyConst.ACCESS_KEY, actual.getParameter("ak"));
Assert.assertTrue(actual.getParameter("data").endsWith("@@group@@aaa"));
String expectSign = SignUtil.sign(actual.getParameter("data"), PropertyKeyConst.SECRET_KEY); String expectSign = SignUtil.sign(actual.getParameter("data"), PropertyKeyConst.SECRET_KEY);
Assert.assertEquals(expectSign, actual.getParameter("signature")); Assert.assertEquals(expectSign, actual.getParameter("signature"));
} }
@Test
public void testDoInjectWithGroupForSts() throws Exception {
prepareForSts();
resource = RequestResource.namingBuilder().setResource("test@@aaa").setGroup("group").build();
LoginIdentityContext actual = new LoginIdentityContext();
namingResourceInjector.doInject(resource, ramContext, actual);
String expectSign = SignUtil.sign(actual.getParameter("data"), "test-sts-sk");
Assert.assertEquals(4, actual.getAllKey().size());
Assert.assertEquals("test-sts-ak", actual.getParameter("ak"));
Assert.assertTrue(actual.getParameter("data").endsWith("@@test@@aaa"));
Assert.assertEquals(expectSign, actual.getParameter("signature"));
}
@Test
public void testDoInjectWithoutGroupForSts() throws Exception {
prepareForSts();
resource = RequestResource.namingBuilder().setResource("aaa").setGroup("group").build();
LoginIdentityContext actual = new LoginIdentityContext();
namingResourceInjector.doInject(resource, ramContext, actual);
String expectSign = SignUtil.sign(actual.getParameter("data"), "test-sts-sk");
Assert.assertEquals(4, actual.getAllKey().size());
Assert.assertEquals("test-sts-ak", actual.getParameter("ak"));
Assert.assertTrue(actual.getParameter("data").endsWith("@@group@@aaa"));
Assert.assertEquals(expectSign, actual.getParameter("signature"));
}
@Test
public void testDoInjectForStsWithException() throws Exception {
prepareForSts();
stsCredential.setExpiration(new Date());
resource = RequestResource.namingBuilder().setResource("aaa").setGroup("group").build();
LoginIdentityContext actual = new LoginIdentityContext();
namingResourceInjector.doInject(resource, ramContext, actual);
Assert.assertEquals(0, actual.getAllKey().size());
}
private void prepareForSts() throws NoSuchFieldException, IllegalAccessException {
StsConfig.getInstance().setSecurityCredentialsUrl("test");
Field field = StsCredentialHolder.class.getDeclaredField("stsCredential");
field.setAccessible(true);
field.set(StsCredentialHolder.getInstance(), stsCredential);
stsCredential.setAccessKeyId("test-sts-ak");
stsCredential.setAccessKeySecret("test-sts-sk");
stsCredential.setSecurityToken("test-sts-token");
stsCredential.setExpiration(new Date(System.currentTimeMillis() + 1000000));
}
private void clearForSts() throws NoSuchFieldException, IllegalAccessException {
StsConfig.getInstance().setSecurityCredentialsUrl(null);
Field field = StsCredentialHolder.class.getDeclaredField("stsCredential");
field.setAccessible(true);
field.set(StsCredentialHolder.getInstance(), null);
}
} }

View File

@ -320,7 +320,7 @@ public class NacosClientPropertiesTest {
"/home/properties_args"); "/home/properties_args");
Assert.assertEquals( Assert.assertEquals(
NacosClientProperties.PROTOTYPE.getPropertyFrom(null, "nacos.home.default.test"), NacosClientProperties.PROTOTYPE.getPropertyFrom(null, "nacos.home.default.test"),
"/home/jvm_args"); NacosClientProperties.PROTOTYPE.getProperty("nacos.home.default.test"));
} }
} }