Skip to content

Commit

Permalink
For #12547, nacos client supports desensitise in logging. (#12578)
Browse files Browse the repository at this point in the history
  • Loading branch information
KomachiSion authored Sep 2, 2024
1 parent 821150d commit 98a6e22
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,11 @@ public LoginIdentityContext getResponse(Properties properties) {
}
return loginIdentityContext;
} catch (Exception e) {
Map<String, String> newBodyMap = new HashMap<>(bodyMap);
newBodyMap.put(PropertyKeyConst.PASSWORD,
ParamUtil.desensitiseParameter(bodyMap.get(PropertyKeyConst.PASSWORD)));
SECURITY_LOGGER.error("[NacosClientAuthServiceImpl] login http request failed"
+ " url: {}, params: {}, bodyMap: {}, errorMsg: {}", url, params, bodyMap, e.getMessage());
+ " url: {}, params: {}, bodyMap: {}, errorMsg: {}", url, params, newBodyMap, e.getMessage());
return null;
}
}
Expand Down
54 changes: 42 additions & 12 deletions client/src/main/java/com/alibaba/nacos/client/utils/ParamUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ public class ParamUtil {

private static final String DEFAULT_PER_TASK_CONFIG_SIZE_KEY = "3000";

private static final int DESENSITISE_PARAMETER_MIN_LENGTH = 2;

private static final int DESENSITISE_PARAMETER_KEEP_ONE_CHAR_LENGTH = 8;

static {
// Client identity information
appKey = NacosClientProperties.PROTOTYPE.getProperty(NACOS_CLIENT_APP_KEY, BLANK_STR);
Expand Down Expand Up @@ -282,25 +286,51 @@ public static String getInputParameters(Properties properties) {
.append("\n"));
} else {
result.append("Nacos client key init properties: \n");
appendKeyParameters(result, properties, PropertyKeyConst.SERVER_ADDR);
appendKeyParameters(result, properties, PropertyKeyConst.NAMESPACE);
appendKeyParameters(result, properties, PropertyKeyConst.ENDPOINT);
appendKeyParameters(result, properties, PropertyKeyConst.ENDPOINT_PORT);
appendKeyParameters(result, properties, PropertyKeyConst.USERNAME);
appendKeyParameters(result, properties, PropertyKeyConst.PASSWORD);
appendKeyParameters(result, properties, PropertyKeyConst.ACCESS_KEY);
appendKeyParameters(result, properties, PropertyKeyConst.SECRET_KEY);
appendKeyParameters(result, properties, PropertyKeyConst.RAM_ROLE_NAME);
appendKeyParameters(result, properties, PropertyKeyConst.SIGNATURE_REGION_ID);
appendKeyParameters(result, properties, PropertyKeyConst.SERVER_ADDR, false);
appendKeyParameters(result, properties, PropertyKeyConst.NAMESPACE, false);
appendKeyParameters(result, properties, PropertyKeyConst.ENDPOINT, false);
appendKeyParameters(result, properties, PropertyKeyConst.ENDPOINT_PORT, false);
appendKeyParameters(result, properties, PropertyKeyConst.USERNAME, false);
appendKeyParameters(result, properties, PropertyKeyConst.PASSWORD, true);
appendKeyParameters(result, properties, PropertyKeyConst.ACCESS_KEY, false);
appendKeyParameters(result, properties, PropertyKeyConst.SECRET_KEY, true);
appendKeyParameters(result, properties, PropertyKeyConst.RAM_ROLE_NAME, false);
appendKeyParameters(result, properties, PropertyKeyConst.SIGNATURE_REGION_ID, false);
}
return result.toString();
}

private static void appendKeyParameters(StringBuilder result, Properties properties, String propertyKey) {
private static void appendKeyParameters(StringBuilder result, Properties properties, String propertyKey,
boolean needDesensitise) {
String propertyValue = properties.getProperty(propertyKey);
if (StringUtils.isBlank(propertyValue)) {
return;
}
result.append("\t").append(propertyKey).append("=").append(propertyValue).append("\n");
result.append("\t").append(propertyKey).append("=")
.append(needDesensitise ? desensitiseParameter(propertyValue) : propertyValue).append("\n");
}

/**
* Do desensitise for parameters with `*` to replace inner content.
*
* @param parameterValue parameter value which need be desensitised.
* @return desensitised parameter value.
*/
public static String desensitiseParameter(String parameterValue) {
if (parameterValue.length() <= DESENSITISE_PARAMETER_MIN_LENGTH) {
return parameterValue;
}
if (parameterValue.length() < DESENSITISE_PARAMETER_KEEP_ONE_CHAR_LENGTH) {
return doDesensitiseParameter(parameterValue, 1);
}
return doDesensitiseParameter(parameterValue, 2);
}

private static String doDesensitiseParameter(String parameterValue, int keepCharCount) {
StringBuilder result = new StringBuilder(parameterValue);
for (int i = keepCharCount; i < parameterValue.length() - keepCharCount; i++) {
result.setCharAt(i, '*');
}
return result.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright 1999-2023 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.impl.process;

import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.auth.impl.NacosAuthLoginConstant;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
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.plugin.auth.api.LoginIdentityContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class HttpLoginProcessorTest {

@Mock
NacosRestTemplate restTemplate;

@Mock
HttpRestResult result;

Properties properties;

HttpLoginProcessor loginProcessor;

@BeforeEach
void setUp() {
loginProcessor = new HttpLoginProcessor(restTemplate);
properties = new Properties();
}

@Test
void testGetResponseSuccess() throws Exception {
properties.setProperty(NacosAuthLoginConstant.SERVER, "http://localhost:8848");
when(restTemplate.postForm(eq("http://localhost:8848/nacos/v1/auth/users/login"), eq(Header.EMPTY),
any(Query.class), anyMap(), eq(String.class))).thenReturn(result);
when(result.ok()).thenReturn(true);
Map<String, String> mockMap = new HashMap<>();
mockMap.put(Constants.ACCESS_TOKEN, "mock_access_token");
mockMap.put(Constants.TOKEN_TTL, "100L");
when(result.getData()).thenReturn(JacksonUtils.toJson(mockMap));
LoginIdentityContext actual = loginProcessor.getResponse(properties);
assertEquals("mock_access_token", actual.getParameter(NacosAuthLoginConstant.ACCESSTOKEN));
assertEquals("100L", actual.getParameter(NacosAuthLoginConstant.TOKENTTL));
}

@Test
void testGetResponseFailed() throws Exception {
properties.setProperty(NacosAuthLoginConstant.SERVER, "localhost");
when(restTemplate.postForm(eq("http://localhost:8848/nacos/v1/auth/users/login"), eq(Header.EMPTY),
any(Query.class), anyMap(), eq(String.class))).thenReturn(result);
assertNull(loginProcessor.getResponse(properties));
}

@Test
void testGetResponseException() throws Exception {
properties.setProperty(NacosAuthLoginConstant.SERVER, "localhost");
when(restTemplate.postForm(eq("http://localhost:8848/nacos/v1/auth/users/login"), eq(Header.EMPTY),
any(Query.class), anyMap(), eq(String.class))).thenThrow(new RuntimeException("test"));
assertNull(loginProcessor.getResponse(properties));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ void testGetInputParametersWithFullMode() {
properties.setProperty(PropertyKeyConst.LOG_ALL_PROPERTIES, "true");
NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
String actual = ParamUtil.getInputParameters(clientProperties.asProperties());
assertTrue(actual.startsWith("Log nacos client init properties with Full mode, This mode is only used for debugging and troubleshooting."));
assertTrue(actual.startsWith(
"Log nacos client init properties with Full mode, This mode is only used for debugging and troubleshooting."));
assertTrue(actual.contains("\ttestKey=testValue\n"));
Properties envProperties = clientProperties.getProperties(SourceType.ENV);
String envCaseKey = envProperties.stringPropertyNames().iterator().next();
Expand All @@ -248,8 +249,22 @@ void testGetInputParameters() {
Properties properties = new Properties();
properties.setProperty("testKey", "testValue");
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "localhost:8848");
properties.setProperty(PropertyKeyConst.PASSWORD, "testPassword");
NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
String actual = ParamUtil.getInputParameters(clientProperties.asProperties());
assertEquals("Nacos client key init properties: \n\tserverAddr=localhost:8848\n", actual);
assertEquals("Nacos client key init properties: \n\tserverAddr=localhost:8848\n\tpassword=te********rd\n",
actual);
}

@Test
void testDesensitiseParameter() {
String shortParameter = "aa";
assertEquals(shortParameter, ParamUtil.desensitiseParameter(shortParameter));
String middleParameter = "aaa";
assertEquals("a*a", ParamUtil.desensitiseParameter(middleParameter));
middleParameter = "aaaaaaa";
assertEquals("a*****a", ParamUtil.desensitiseParameter(middleParameter));
String longParameter = "testPass";
assertEquals("te****ss", ParamUtil.desensitiseParameter(longParameter));
}
}

0 comments on commit 98a6e22

Please sign in to comment.