Skip to content

Commit 9e20be9

Browse files
committed
duplicate fields to log in message. add tests.
1 parent 6da450d commit 9e20be9

File tree

6 files changed

+228
-23
lines changed

6 files changed

+228
-23
lines changed

oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ public AccessToken refreshAccessToken() throws IOException {
548548

549549
HttpResponse response = null;
550550
try {
551-
LoggingUtils.logRequest(request, LOGGER, "Sending auth refresh access token request");
551+
LoggingUtils.logRequest(request, LOGGER, "Sending auth request to refresh access token");
552552
response = request.execute();
553553
LoggingUtils.logResponse(response, LOGGER, "Received auth response for access token");
554554
} catch (IOException e) {

oauth2_http/java/com/google/auth/oauth2/LoggingUtils.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,41 @@
3434
import com.google.api.client.http.HttpRequest;
3535
import com.google.api.client.http.HttpResponse;
3636
import com.google.api.client.http.UrlEncodedContent;
37+
import com.google.api.client.http.json.JsonHttpContent;
3738
import com.google.api.client.util.GenericData;
39+
import com.google.gson.Gson;
3840
import java.nio.charset.StandardCharsets;
3941
import java.security.MessageDigest;
4042
import java.security.NoSuchAlgorithmException;
43+
import java.util.Arrays;
4144
import java.util.HashMap;
45+
import java.util.HashSet;
4246
import java.util.Map;
47+
import java.util.Set;
4348
import org.slf4j.Logger;
4449
import org.slf4j.MDC;
4550

4651
class LoggingUtils {
4752

53+
private static final Gson gson = new Gson();
54+
private static final Set<String> sensitiveKeys =
55+
new HashSet<>(
56+
Arrays.asList(
57+
"token",
58+
"assertion",
59+
"access_token",
60+
"client_secret",
61+
"refresh_token",
62+
"signedBlob"));
63+
4864
private LoggingUtils() {}
4965

5066
static void logWithMDC(
5167
Logger logger, org.slf4j.event.Level level, Map<String, String> contextMap, String message) {
5268
if (!contextMap.isEmpty()) {
5369
contextMap.forEach(MDC::put);
70+
contextMap.put("message", message);
71+
message = gson.toJson(contextMap);
5472
}
5573
switch (level) {
5674
case TRACE:
@@ -100,10 +118,15 @@ static void logRequest(HttpRequest request, Logger logger, String message) {
100118

101119
if (request.getContent() != null && logger.isDebugEnabled()) {
102120
// are payload always GenericData? If so, can parse and store in json
103-
GenericData data = (GenericData) ((UrlEncodedContent) request.getContent()).getData();
104-
105-
Map<String, String> contextMap = parseGenericData(data);
106-
loggingDataMap.put("request.payload", contextMap.toString());
121+
if (request.getContent() instanceof UrlEncodedContent) {
122+
123+
GenericData data = (GenericData) ((UrlEncodedContent) request.getContent()).getData();
124+
Map<String, String> contextMap = parseGenericData(data);
125+
loggingDataMap.put("request.payload", contextMap.toString());
126+
} else if (request.getContent() instanceof JsonHttpContent) {
127+
String data = ((JsonHttpContent) request.getContent()).getData().toString();
128+
loggingDataMap.put("request.payload", data);
129+
}
107130

108131
logWithMDC(logger, org.slf4j.event.Level.DEBUG, loggingDataMap, message);
109132
} else {
@@ -148,11 +171,7 @@ private static Map<String, String> parseGenericData(GenericData genericData) {
148171
Map<String, String> contextMap = new HashMap<>();
149172
genericData.forEach(
150173
(key, val) -> {
151-
if ("token".equals(key)
152-
|| "assertion".equals(key)
153-
|| "access_token".equals(key)
154-
|| "client_secret".equals(key)
155-
|| "refresh_token".equals(key)) {
174+
if (sensitiveKeys.contains(key)) {
156175
String secretString = String.valueOf(val);
157176
String hashedVal = calculateSHA256Hash(secretString);
158177
contextMap.put(key, hashedVal);

oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ public class ImpersonatedCredentialsTest extends BaseSerializationTest {
118118
private static final String PROJECT_ID = "project-id";
119119
public static final String IMPERSONATED_CLIENT_EMAIL =
120120
121-
private static final List<String> IMMUTABLE_SCOPES_LIST = ImmutableList.of("scope1", "scope2");
122-
private static final int VALID_LIFETIME = 300;
121+
static final List<String> IMMUTABLE_SCOPES_LIST = ImmutableList.of("scope1", "scope2");
122+
static final int VALID_LIFETIME = 300;
123123
private static final int INVALID_LIFETIME = 43210;
124124
private static JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
125125

@@ -162,7 +162,7 @@ public void setup() throws IOException {
162162
mockTransportFactory = new MockIAMCredentialsServiceTransportFactory();
163163
}
164164

165-
private GoogleCredentials getSourceCredentials() throws IOException {
165+
static GoogleCredentials getSourceCredentials() throws IOException {
166166
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
167167
PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
168168
ServiceAccountCredentials sourceCredentials =

oauth2_http/javatests/com/google/auth/oauth2/LoggingTest.java

Lines changed: 184 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,33 @@
3131

3232
package com.google.auth.oauth2;
3333

34+
import static com.google.auth.TestUtils.getDefaultExpireTime;
35+
import static com.google.auth.oauth2.ImpersonatedCredentialsTest.DEFAULT_IMPERSONATION_URL;
36+
import static com.google.auth.oauth2.ImpersonatedCredentialsTest.IMMUTABLE_SCOPES_LIST;
37+
import static com.google.auth.oauth2.ImpersonatedCredentialsTest.IMPERSONATED_CLIENT_EMAIL;
38+
import static com.google.auth.oauth2.ImpersonatedCredentialsTest.TOKEN_WITH_EMAIL;
39+
import static com.google.auth.oauth2.ImpersonatedCredentialsTest.VALID_LIFETIME;
3440
import static com.google.auth.oauth2.ServiceAccountCredentialsTest.ACCESS_TOKEN;
3541
import static com.google.auth.oauth2.ServiceAccountCredentialsTest.CALL_URI;
3642
import static com.google.auth.oauth2.ServiceAccountCredentialsTest.CLIENT_EMAIL;
3743
import static com.google.auth.oauth2.ServiceAccountCredentialsTest.DEFAULT_ID_TOKEN;
3844
import static com.google.auth.oauth2.ServiceAccountCredentialsTest.SCOPES;
3945
import static com.google.auth.oauth2.ServiceAccountCredentialsTest.createDefaultBuilder;
46+
import static com.google.auth.oauth2.UserCredentialsTest.CLIENT_ID;
47+
import static com.google.auth.oauth2.UserCredentialsTest.CLIENT_SECRET;
48+
import static com.google.auth.oauth2.UserCredentialsTest.REFRESH_TOKEN;
49+
import static org.junit.Assert.assertArrayEquals;
4050
import static org.junit.Assert.assertEquals;
51+
import static org.junit.Assert.assertTrue;
4152

4253
import com.google.api.client.http.HttpStatusCodes;
54+
import com.google.api.client.json.webtoken.JsonWebToken.Payload;
4355
import com.google.auth.TestAppender;
4456
import com.google.auth.TestUtils;
57+
import com.google.gson.Gson;
58+
import com.google.gson.JsonObject;
4559
import java.io.IOException;
60+
import java.util.Arrays;
4661
import java.util.List;
4762
import java.util.Map;
4863
import org.junit.Test;
@@ -51,6 +66,8 @@
5166

5267
public class LoggingTest {
5368

69+
private static final Gson gson = new Gson();
70+
5471
private TestAppender setupTestLogger(Class<?> clazz) {
5572
TestAppender testAppender = new TestAppender();
5673
testAppender.start();
@@ -60,7 +77,37 @@ private TestAppender setupTestLogger(Class<?> clazz) {
6077
}
6178

6279
@Test
63-
public void getRequestMetadata_hasAccessToken() throws IOException {
80+
public void userCredentials_getRequestMetadata_fromRefreshToken_hasAccessToken()
81+
throws IOException {
82+
TestAppender testAppender = setupTestLogger(UserCredentials.class);
83+
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
84+
transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
85+
transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
86+
UserCredentials userCredentials =
87+
UserCredentials.newBuilder()
88+
.setClientId(CLIENT_ID)
89+
.setClientSecret(CLIENT_SECRET)
90+
.setRefreshToken(REFRESH_TOKEN)
91+
.setHttpTransportFactory(transportFactory)
92+
.build();
93+
94+
Map<String, List<String>> metadata = userCredentials.getRequestMetadata(CALL_URI);
95+
96+
TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN);
97+
98+
assertEquals(3, testAppender.events.size());
99+
JsonObject jsonMessage =
100+
gson.fromJson(testAppender.events.get(0).getFormattedMessage(), JsonObject.class);
101+
102+
assertEquals(
103+
"com.google.auth.oauth2.UserCredentials", testAppender.events.get(0).getLoggerName());
104+
assertEquals(
105+
"Sending auth request to refresh access token", jsonMessage.get("message").getAsString());
106+
testAppender.stop();
107+
}
108+
109+
@Test
110+
public void serviceAccountCredentials_getRequestMetadata_hasAccessToken() throws IOException {
64111
TestAppender testAppender = setupTestLogger(ServiceAccountCredentials.class);
65112
GoogleCredentials credentials =
66113
ServiceAccountCredentialsTest.createDefaultBuilderWithToken(ACCESS_TOKEN)
@@ -70,14 +117,17 @@ public void getRequestMetadata_hasAccessToken() throws IOException {
70117
TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN);
71118

72119
assertEquals(3, testAppender.events.size());
120+
JsonObject jsonMessage =
121+
gson.fromJson(testAppender.events.get(0).getFormattedMessage(), JsonObject.class);
122+
73123
assertEquals(
74-
"Sending auth request to refresh access token",
75-
testAppender.events.get(0).getFormattedMessage());
124+
"Sending auth request to refresh access token", jsonMessage.get("message").getAsString());
76125
testAppender.stop();
77126
}
78127

79128
@Test
80-
public void idTokenWithAudience_iamFlow_targetAudienceMatchesAudClaim() throws IOException {
129+
public void serviceAccountCredentials_idTokenWithAudience_iamFlow_targetAudienceMatchesAudClaim()
130+
throws IOException {
81131
TestAppender testAppender = setupTestLogger(ServiceAccountCredentials.class);
82132
String nonGDU = "test.com";
83133
MockIAMCredentialsServiceTransportFactory transportFactory =
@@ -108,11 +158,139 @@ public void idTokenWithAudience_iamFlow_targetAudienceMatchesAudClaim() throws I
108158
tokenCredential.getIdToken().getJsonWebSignature().getPayload().getAudience());
109159

110160
assertEquals(2, testAppender.events.size());
161+
162+
JsonObject jsonMessage1 =
163+
gson.fromJson(testAppender.events.get(0).getFormattedMessage(), JsonObject.class);
164+
JsonObject jsonMessage2 =
165+
gson.fromJson(testAppender.events.get(1).getFormattedMessage(), JsonObject.class);
111166
assertEquals(
112167
"Sending Auth request to get id token via Iam Endpoint",
113-
testAppender.events.get(0).getFormattedMessage());
114-
assertEquals("Auth response payload", testAppender.events.get(1).getFormattedMessage());
168+
jsonMessage1.get("message").getAsString());
169+
assertEquals("Auth response payload", jsonMessage2.get("message").getAsString());
170+
171+
testAppender.stop();
172+
}
173+
174+
@Test()
175+
public void impersonatedCredentials_refreshAccessToken_success()
176+
throws IOException, IllegalStateException {
177+
TestAppender testAppender = setupTestLogger(ImpersonatedCredentials.class);
178+
MockIAMCredentialsServiceTransportFactory mockTransportFactory =
179+
new MockIAMCredentialsServiceTransportFactory();
180+
mockTransportFactory.getTransport().setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL);
181+
mockTransportFactory.getTransport().setAccessToken(ACCESS_TOKEN);
182+
mockTransportFactory.getTransport().setExpireTime(getDefaultExpireTime());
183+
mockTransportFactory.getTransport().addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, "");
184+
ImpersonatedCredentials targetCredentials =
185+
ImpersonatedCredentials.create(
186+
ImpersonatedCredentialsTest.getSourceCredentials(),
187+
IMPERSONATED_CLIENT_EMAIL,
188+
null,
189+
IMMUTABLE_SCOPES_LIST,
190+
VALID_LIFETIME,
191+
mockTransportFactory);
115192

193+
assertEquals(ACCESS_TOKEN, targetCredentials.refreshAccessToken().getTokenValue());
194+
assertEquals(
195+
DEFAULT_IMPERSONATION_URL, mockTransportFactory.getTransport().getRequest().getUrl());
196+
197+
// verify metrics header added and authorization header intact
198+
Map<String, List<String>> requestHeader =
199+
mockTransportFactory.getTransport().getRequest().getHeaders();
200+
com.google.auth.oauth2.TestUtils.validateMetricsHeader(requestHeader, "at", "imp");
201+
assertTrue(requestHeader.containsKey("authorization"));
202+
203+
assertEquals(3, testAppender.events.size());
204+
JsonObject jsonMessage =
205+
gson.fromJson(testAppender.events.get(0).getFormattedMessage(), JsonObject.class);
206+
207+
assertEquals(
208+
"com.google.auth.oauth2.ImpersonatedCredentials",
209+
testAppender.events.get(0).getLoggerName());
210+
assertEquals(
211+
"Sending auth request to refresh access token", jsonMessage.get("message").getAsString());
212+
assertEquals(4, testAppender.events.get(0).getMDCPropertyMap().size());
213+
testAppender.stop();
214+
}
215+
216+
@Test
217+
public void idTokenWithAudience_withEmail() throws IOException {
218+
TestAppender testAppender = setupTestLogger(IamUtils.class);
219+
MockIAMCredentialsServiceTransportFactory mockTransportFactory =
220+
new MockIAMCredentialsServiceTransportFactory();
221+
mockTransportFactory.getTransport().setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL);
222+
mockTransportFactory.getTransport().setAccessToken(ACCESS_TOKEN);
223+
mockTransportFactory.getTransport().setExpireTime(getDefaultExpireTime());
224+
mockTransportFactory.getTransport().addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, "");
225+
226+
ImpersonatedCredentials targetCredentials =
227+
ImpersonatedCredentials.create(
228+
ImpersonatedCredentialsTest.getSourceCredentials(),
229+
IMPERSONATED_CLIENT_EMAIL,
230+
null,
231+
IMMUTABLE_SCOPES_LIST,
232+
VALID_LIFETIME,
233+
mockTransportFactory);
234+
235+
mockTransportFactory.getTransport().setIdToken(TOKEN_WITH_EMAIL);
236+
237+
String targetAudience = "https://foo.bar";
238+
IdTokenCredentials tokenCredential =
239+
IdTokenCredentials.newBuilder()
240+
.setIdTokenProvider(targetCredentials)
241+
.setTargetAudience(targetAudience)
242+
.setOptions(Arrays.asList(IdTokenProvider.Option.INCLUDE_EMAIL))
243+
.build();
244+
tokenCredential.refresh();
245+
assertEquals(TOKEN_WITH_EMAIL, tokenCredential.getAccessToken().getTokenValue());
246+
Payload p = tokenCredential.getIdToken().getJsonWebSignature().getPayload();
247+
assertTrue(p.containsKey("email"));
248+
249+
assertEquals(3, testAppender.events.size());
250+
JsonObject jsonMessage =
251+
gson.fromJson(testAppender.events.get(0).getFormattedMessage(), JsonObject.class);
252+
253+
assertEquals("com.google.auth.oauth2.IamUtils", testAppender.events.get(0).getLoggerName());
254+
assertEquals("Sending auth request to get id token", jsonMessage.get("message").getAsString());
255+
assertEquals(4, testAppender.events.get(0).getMDCPropertyMap().size());
256+
testAppender.stop();
257+
}
258+
259+
@Test
260+
public void sign_sameAs() throws IOException {
261+
TestAppender testAppender = setupTestLogger(IamUtils.class);
262+
MockIAMCredentialsServiceTransportFactory mockTransportFactory =
263+
new MockIAMCredentialsServiceTransportFactory();
264+
mockTransportFactory.getTransport().setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL);
265+
mockTransportFactory.getTransport().setAccessToken(ACCESS_TOKEN);
266+
mockTransportFactory.getTransport().setExpireTime(getDefaultExpireTime());
267+
mockTransportFactory.getTransport().addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, "");
268+
ImpersonatedCredentials targetCredentials =
269+
ImpersonatedCredentials.create(
270+
ImpersonatedCredentialsTest.getSourceCredentials(),
271+
IMPERSONATED_CLIENT_EMAIL,
272+
null,
273+
IMMUTABLE_SCOPES_LIST,
274+
VALID_LIFETIME,
275+
mockTransportFactory);
276+
277+
byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD};
278+
279+
mockTransportFactory.getTransport().setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL);
280+
mockTransportFactory.getTransport().setSignedBlob(expectedSignature);
281+
282+
assertArrayEquals(expectedSignature, targetCredentials.sign(expectedSignature));
283+
284+
assertEquals(3, testAppender.events.size());
285+
JsonObject jsonMessage =
286+
gson.fromJson(testAppender.events.get(0).getFormattedMessage(), JsonObject.class);
287+
288+
assertEquals("com.google.auth.oauth2.IamUtils", testAppender.events.get(0).getLoggerName());
289+
assertEquals(
290+
"Sending auth request to get signature to sign the blob",
291+
jsonMessage.get("message").getAsString());
292+
assertEquals(4, testAppender.events.get(0).getMDCPropertyMap().size());
293+
assertEquals(1, testAppender.events.get(2).getMDCPropertyMap().size());
116294
testAppender.stop();
117295
}
118296
}

oauth2_http/javatests/com/google/auth/oauth2/LoggingUtilsTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import ch.qos.logback.classic.spi.ILoggingEvent;
3737
import com.google.api.client.util.GenericData;
3838
import com.google.auth.TestAppender;
39+
import com.google.gson.Gson;
40+
import com.google.gson.JsonObject;
3941
import java.util.HashMap;
4042
import java.util.Map;
4143
import org.junit.Test;
@@ -46,6 +48,7 @@
4648

4749
public class LoggingUtilsTest {
4850
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingUtilsTest.class);
51+
private static final Gson gson = new Gson();
4952

5053
private TestAppender setupTestLogger() {
5154
TestAppender testAppender = new TestAppender();
@@ -65,7 +68,12 @@ public void testLogWithMDC_slf4jLogger() {
6568
LoggingUtils.logWithMDC(LOGGER, Level.DEBUG, contextMap, "test message");
6669

6770
assertEquals(1, testAppender.events.size());
68-
assertEquals("test message", testAppender.events.get(0).getFormattedMessage());
71+
72+
JsonObject jsonMessage =
73+
gson.fromJson(testAppender.events.get(0).getFormattedMessage(), JsonObject.class);
74+
assertEquals("test message", jsonMessage.get("message").getAsString());
75+
assertEquals("value1", jsonMessage.get("key1").getAsString());
76+
assertEquals("value2", jsonMessage.get("key2").getAsString());
6977

7078
// Verify MDC content
7179
ILoggingEvent event = testAppender.events.get(0);

oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@
7070
@RunWith(JUnit4.class)
7171
public class UserCredentialsTest extends BaseSerializationTest {
7272

73-
private static final String CLIENT_SECRET = "jakuaL9YyieakhECKL2SwZcu";
74-
private static final String CLIENT_ID = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws";
75-
private static final String REFRESH_TOKEN = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
73+
static final String CLIENT_SECRET = "jakuaL9YyieakhECKL2SwZcu";
74+
static final String CLIENT_ID = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws";
75+
static final String REFRESH_TOKEN = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
7676
private static final String ACCESS_TOKEN = "1/MkSJoj1xsli0AccessToken_NKPY2";
7777
private static final String QUOTA_PROJECT = "sample-quota-project-id";
7878
private static final Collection<String> SCOPES = Collections.singletonList("dummy.scope");

0 commit comments

Comments
 (0)