[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:
parent
02a5e38981
commit
383287c616
@ -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";
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user