Skip to content

Commit d67a4e8

Browse files
committed
Added telemetry Support
1 parent 9379b76 commit d67a4e8

File tree

5 files changed

+140
-1
lines changed

5 files changed

+140
-1
lines changed

auth0-api-java/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ repositories {
4444
mavenCentral()
4545
}
4646

47+
processResources {
48+
filesMatching('auth0-client-info.properties') {
49+
expand(version: project.version)
50+
}
51+
}
52+
4753
test {
4854
useJUnit()
4955
testLogging {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.auth0.telemetry;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.nio.charset.StandardCharsets;
6+
import java.util.Properties;
7+
8+
/**
9+
* Provides the Base64-encoded Auth0-Client telemetry header value.
10+
*
11+
* The payload is a JSON object: {"name":"springboot-api","version":"x.y.z","java":"17"}
12+
*/
13+
public final class TelemetryProvider {
14+
15+
private static final String PROPERTIES_FILE = "auth0-client-info.properties";
16+
private static final String UNKNOWN = "unknown";
17+
18+
private static volatile String cachedHeaderValue;
19+
20+
private TelemetryProvider() {
21+
}
22+
23+
/**
24+
* Returns the Base64url-encoded telemetry header value.
25+
*
26+
* @return the Auth0-Client header value, or null if it cannot be built
27+
*/
28+
public static String getHeaderValue() {
29+
if (cachedHeaderValue != null) {
30+
return cachedHeaderValue;
31+
}
32+
synchronized (TelemetryProvider.class) {
33+
if (cachedHeaderValue != null) {
34+
return cachedHeaderValue;
35+
}
36+
cachedHeaderValue = buildHeaderValue();
37+
return cachedHeaderValue;
38+
}
39+
}
40+
41+
private static String buildHeaderValue() {
42+
String name = UNKNOWN;
43+
String version = UNKNOWN;
44+
45+
try (InputStream is = TelemetryProvider.class.getClassLoader()
46+
.getResourceAsStream(PROPERTIES_FILE)) {
47+
if (is != null) {
48+
Properties props = new Properties();
49+
props.load(is);
50+
name = props.getProperty("name", UNKNOWN);
51+
version = props.getProperty("version", UNKNOWN);
52+
}
53+
} catch (IOException ignored) {
54+
// Fall through with defaults
55+
}
56+
57+
String javaVersion = System.getProperty("java.version", UNKNOWN);
58+
59+
String json = "{\"name\":\"" + name + "\",\"version\":\"" + version + "\",\"java\":\"" + javaVersion + "\"}";
60+
61+
return java.util.Base64.getUrlEncoder().withoutPadding()
62+
.encodeToString(json.getBytes(StandardCharsets.UTF_8));
63+
}
64+
}

auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212
import com.auth0.jwt.algorithms.Algorithm;
1313
import com.auth0.jwt.interfaces.DecodedJWT;
1414
import com.auth0.models.HttpRequestInfo;
15+
import com.auth0.telemetry.TelemetryProvider;
1516

17+
import java.net.MalformedURLException;
18+
import java.net.URI;
19+
import java.net.URISyntaxException;
20+
import java.net.URL;
1621
import java.security.interfaces.RSAPublicKey;
22+
import java.util.HashMap;
1723
import java.util.Map;
1824

1925
import static com.auth0.jwt.JWT.require;
@@ -41,7 +47,7 @@ public JWTValidator(AuthOptions authOptions) {
4147
}
4248

4349
this.authOptions = authOptions;
44-
this.jwkProvider = new UrlJwkProvider(authOptions.getDomain());
50+
this.jwkProvider = createJwkProvider(authOptions.getDomain());
4551
}
4652

4753
/**
@@ -170,6 +176,28 @@ private BaseAuthException wrapAsValidationException(Exception e) {
170176
return new VerifyAccessTokenException("JWT claim validation failed");
171177
}
172178

179+
private static JwkProvider createJwkProvider(String domain) {
180+
Map<String, String> headers = new HashMap<>();
181+
headers.put("Accept", "application/json");
182+
183+
String telemetry = TelemetryProvider.getHeaderValue();
184+
if (telemetry != null) {
185+
headers.put("Auth0-Client", telemetry);
186+
}
187+
188+
String normalizedDomain = domain;
189+
if (!normalizedDomain.startsWith("http")) {
190+
normalizedDomain = "https://" + normalizedDomain;
191+
}
192+
try {
193+
URI uri = new URI(normalizedDomain + "/.well-known/jwks.json").normalize();
194+
URL url = uri.toURL();
195+
return new UrlJwkProvider(url, null, null, null, headers);
196+
} catch (URISyntaxException | MalformedURLException e) {
197+
throw new IllegalArgumentException("Invalid domain: " + domain, e);
198+
}
199+
}
200+
173201
public AuthOptions getAuthOptions() {
174202
return authOptions;
175203
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
version=${version}
2+
name=springboot-api
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.auth0.telemetry;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import org.junit.Test;
5+
6+
import java.nio.charset.StandardCharsets;
7+
import java.util.Base64;
8+
import java.util.Map;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
public class TelemetryProviderTest {
13+
14+
@Test
15+
@SuppressWarnings("unchecked")
16+
public void getHeaderValue_returnsValidBase64Json() throws Exception {
17+
String headerValue = TelemetryProvider.getHeaderValue();
18+
assertThat(headerValue).isNotNull().isNotEmpty();
19+
20+
byte[] decoded = Base64.getUrlDecoder().decode(headerValue);
21+
String json = new String(decoded, StandardCharsets.UTF_8);
22+
23+
ObjectMapper mapper = new ObjectMapper();
24+
Map<String, String> payload = mapper.readValue(json, Map.class);
25+
26+
assertThat(payload).containsKey("name");
27+
assertThat(payload).containsKey("version");
28+
assertThat(payload).containsKey("java");
29+
assertThat(payload.get("name")).isEqualTo("springboot-api");
30+
assertThat(payload.get("java")).isEqualTo(System.getProperty("java.version"));
31+
}
32+
33+
@Test
34+
public void getHeaderValue_isCached() {
35+
String first = TelemetryProvider.getHeaderValue();
36+
String second = TelemetryProvider.getHeaderValue();
37+
assertThat(first).isSameAs(second);
38+
}
39+
}

0 commit comments

Comments
 (0)