Skip to content

Commit 19aaaf1

Browse files
committed
Remove nimbus from main library
1 parent 8d1f418 commit 19aaaf1

File tree

12 files changed

+122
-147
lines changed

12 files changed

+122
-147
lines changed

msal4j-sdk/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<groupId>com.nimbusds</groupId>
3838
<artifactId>oauth2-oidc-sdk</artifactId>
3939
<version>11.23</version>
40+
<scope>test</scope>
4041
</dependency>
4142
<dependency>
4243
<groupId>net.minidev</groupId>

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/AuthenticationResult.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33

44
package com.microsoft.aad.msal4j;
55

6-
import com.nimbusds.jwt.JWTParser;
76
import lombok.AccessLevel;
87
import lombok.Builder;
98
import lombok.EqualsAndHashCode;
109
import lombok.Getter;
1110
import lombok.experimental.Accessors;
1211

13-
import java.io.Serializable;
14-
import java.text.ParseException;
1512
import java.util.Date;
1613

1714
@Accessors(fluent = true)
@@ -45,14 +42,8 @@ private IdToken getIdTokenObj() {
4542
if (StringHelper.isBlank(idToken)) {
4643
return null;
4744
}
48-
try {
49-
String idTokenJson = JWTParser.parse(idToken).getParsedParts()[1].decodeToString();
5045

51-
return JsonHelper.convertJsonToObject(idTokenJson, IdToken.class);
52-
} catch (ParseException e) {
53-
e.printStackTrace();
54-
}
55-
return null;
46+
return JsonHelper.createIdTokenFromEncodedTokenString(idToken);
5647
}
5748

5849
@Getter(value = AccessLevel.PACKAGE)
@@ -76,12 +67,7 @@ private ITenantProfile getTenantProfile() {
7667
return null;
7768
}
7869

79-
try {
80-
return new TenantProfile(JWTParser.parse(idToken).getJWTClaimsSet().getClaims(),
81-
getAccount().environment());
82-
} catch (ParseException e) {
83-
throw new MsalClientException("Cached JWT could not be parsed: " + e.getMessage(), AuthenticationErrorCode.INVALID_JWT);
84-
}
70+
return new TenantProfile(JsonHelper.parseJsonToMap(JsonHelper.getTokenPayloadClaims(idToken)), getAccount().environment());
8571
}
8672

8773
private String environment;

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/CustomJWTAuthentication.java

Lines changed: 0 additions & 63 deletions
This file was deleted.

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/HttpHelper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class HttpHelper implements IHttpHelper {
2323

2424
public static final int HTTP_STATUS_200 = 200;
2525
public static final int HTTP_STATUS_400 = 400;
26+
public static final int HTTP_STATUS_401 = 401;
2627
public static final int HTTP_STATUS_429 = 429;
2728
public static final int HTTP_STATUS_500 = 500;
2829

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/JsonHelper.java

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.azure.json.JsonProviders;
77
import com.azure.json.JsonReader;
88
import com.azure.json.JsonSerializable;
9+
import com.azure.json.JsonToken;
910
import com.azure.json.ReadValueCallback;
1011
import com.fasterxml.jackson.annotation.JsonInclude;
1112
import com.fasterxml.jackson.core.JsonParser;
@@ -40,15 +41,77 @@ static <T> T convertJsonToObject(final String json, final Class<T> tClass) {
4041
}
4142

4243
static IdToken createIdTokenFromEncodedTokenString(String token) {
43-
String idTokenJson;
44+
return JsonHelper.convertJsonToObject(getTokenPayloadClaims(token), IdToken.class);
45+
}
46+
47+
static String getTokenPayloadClaims(String token) {
4448
try {
45-
idTokenJson = new String(Base64.getUrlDecoder().decode(token.split("\\.")[1]), StandardCharsets.UTF_8);
49+
return new String(Base64.getUrlDecoder().decode(token.split("\\.")[1]), StandardCharsets.UTF_8);
4650
} catch (ArrayIndexOutOfBoundsException e) {
4751
throw new MsalClientException("Error parsing ID token, missing payload section.",
4852
AuthenticationErrorCode.INVALID_JWT);
4953
}
54+
}
55+
56+
//Converts a generic JSON string to a Map<String, Object> with relevant types
57+
static Map<String, Object> parseJsonToMap(String jsonString) {
58+
if (StringHelper.isBlank(jsonString)) {
59+
return new HashMap<>();
60+
}
61+
62+
try (JsonReader jsonReader = JsonProviders.createReader(jsonString)) {
63+
jsonReader.nextToken();
64+
return parseJsonObject(jsonReader);
65+
} catch (IOException e) {
66+
throw new MsalJsonParsingException(e.getMessage(), AuthenticationErrorCode.INVALID_JSON);
67+
}
68+
}
69+
70+
private static List<Object> parseJsonArray(JsonReader jsonReader) throws IOException {
71+
List<Object> array = new ArrayList<>();
72+
73+
while (jsonReader.nextToken() != JsonToken.END_ARRAY) {
74+
array.add(parseValue(jsonReader));
75+
}
76+
77+
return array;
78+
}
79+
80+
private static Map<String, Object> parseJsonObject(JsonReader jsonReader) throws IOException {
81+
Map<String, Object> object = new HashMap<>();
5082

51-
return JsonHelper.convertJsonToObject(idTokenJson, IdToken.class);
83+
while (jsonReader.nextToken() != JsonToken.END_OBJECT) {
84+
String fieldName = jsonReader.getFieldName();
85+
object.put(fieldName, parseValue(jsonReader));
86+
}
87+
88+
return object;
89+
}
90+
91+
private static Object parseValue(JsonReader jsonReader) throws IOException {
92+
JsonToken token = jsonReader.currentToken();
93+
94+
switch (token) {
95+
case STRING:
96+
return jsonReader.getString();
97+
case NUMBER:
98+
try {
99+
return jsonReader.getLong();
100+
} catch (ArithmeticException e) {
101+
return jsonReader.getDouble();
102+
}
103+
case BOOLEAN:
104+
return jsonReader.getBoolean();
105+
case NULL:
106+
return null;
107+
case START_ARRAY:
108+
return parseJsonArray(jsonReader);
109+
case START_OBJECT:
110+
return parseJsonObject(jsonReader);
111+
default:
112+
jsonReader.skipChildren();
113+
return null;
114+
}
52115
}
53116

54117
//This method is used to convert a JSON string to an object which implements the JsonSerializable interface from com.azure.json

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/TokenCache.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
import com.fasterxml.jackson.annotation.JsonProperty;
77
import com.fasterxml.jackson.databind.JsonNode;
88
import com.fasterxml.jackson.databind.node.ObjectNode;
9-
import com.nimbusds.jwt.JWTParser;
109

1110
import java.io.IOException;
12-
import java.text.ParseException;
1311
import java.util.*;
1412
import java.util.concurrent.locks.ReadWriteLock;
1513
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -331,7 +329,7 @@ Set<IAccount> getAccounts(String clientId) {
331329

332330
ITenantProfile profile = null;
333331
if (idToken != null) {
334-
Map<String, ?> idTokenClaims = JWTParser.parse(idToken.secret()).getJWTClaimsSet().getClaims();
332+
Map<String, ?> idTokenClaims = JsonHelper.parseJsonToMap(JsonHelper.getTokenPayloadClaims(idToken.secret));
335333
profile = new TenantProfile(idTokenClaims, accCached.environment());
336334
}
337335

@@ -352,8 +350,6 @@ Set<IAccount> getAccounts(String clientId) {
352350
}
353351

354352
return new HashSet<>(rootAccounts.values());
355-
} catch (ParseException e) {
356-
throw new MsalClientException("Cached JWT could not be parsed: " + e.getMessage(), AuthenticationErrorCode.INVALID_JWT);
357353
} finally {
358354
lock.readLock().unlock();
359355
}

msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/ClientCertificateTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
package com.microsoft.aad.msal4j;
55

6-
import com.nimbusds.oauth2.sdk.auth.PrivateKeyJWT;
76
import org.junit.jupiter.api.Test;
87
import org.junit.jupiter.api.TestInstance;
98

msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/ManagedIdentityTests.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33

44
package com.microsoft.aad.msal4j;
55

6-
import com.nimbusds.oauth2.sdk.util.URLUtils;
7-
import labapi.App;
86
import org.junit.jupiter.api.Nested;
97
import org.junit.jupiter.api.Test;
108
import org.junit.jupiter.api.TestInstance;
119
import org.junit.jupiter.api.extension.ExtendWith;
1210
import org.junit.jupiter.params.ParameterizedTest;
1311
import org.junit.jupiter.params.provider.MethodSource;
1412
import org.junit.jupiter.params.provider.ValueSource;
15-
import org.mockito.ArgumentCaptor;
1613
import org.mockito.junit.jupiter.MockitoExtension;
1714

1815
import java.net.SocketException;
@@ -78,69 +75,69 @@ private HttpRequest expectedRequest(ManagedIdentitySourceType source, String res
7875
ManagedIdentityId id) {
7976
String endpoint = null;
8077
Map<String, String> headers = new HashMap<>();
81-
Map<String, List<String>> queryParameters = new HashMap<>();
78+
Map<String, String> queryParameters = new HashMap<>();
8279

8380
switch (source) {
8481
case APP_SERVICE:
8582
endpoint = appServiceEndpoint;
86-
queryParameters.put("api-version", Collections.singletonList("2019-08-01"));
87-
queryParameters.put("resource", Collections.singletonList(resource));
83+
queryParameters.put("api-version", "2019-08-01");
84+
queryParameters.put("resource", resource);
8885
headers.put("X-IDENTITY-HEADER", "secret");
8986
break;
9087
case CLOUD_SHELL:
9188
endpoint = cloudShellEndpoint;
9289
headers.put("ContentType", "application/x-www-form-urlencoded");
9390
headers.put("Metadata", "true");
94-
queryParameters.put("resource", Collections.singletonList(resource));
91+
queryParameters.put("resource", resource);
9592
break;
9693
case IMDS:
9794
endpoint = IMDS_ENDPOINT;
98-
queryParameters.put("api-version", Collections.singletonList("2018-02-01"));
99-
queryParameters.put("resource", Collections.singletonList(resource));
95+
queryParameters.put("api-version", "2018-02-01");
96+
queryParameters.put("resource", resource);
10097
headers.put("Metadata", "true");
10198
break;
10299
case AZURE_ARC:
103100
endpoint = azureArcEndpoint;
104-
queryParameters.put("api-version", Collections.singletonList("2019-11-01"));
105-
queryParameters.put("resource", Collections.singletonList(resource));
101+
queryParameters.put("api-version", "2019-11-01");
102+
queryParameters.put("resource", resource);
106103
headers.put("Metadata", "true");
107104
break;
108105
case SERVICE_FABRIC:
109106
endpoint = serviceFabricEndpoint;
110-
queryParameters.put("api-version", Collections.singletonList("2019-07-01-preview"));
111-
queryParameters.put("resource", Collections.singletonList(resource));
107+
queryParameters.put("api-version", "2019-07-01-preview");
108+
queryParameters.put("resource", resource);
112109
headers.put("secret", "secret");
113110
break;
114111
case NONE:
115112
case DEFAULT_TO_IMDS:
116113
endpoint = IMDS_ENDPOINT;
117-
queryParameters.put("api-version", Collections.singletonList("2018-02-01"));
118-
queryParameters.put("resource", Collections.singletonList(resource));
114+
queryParameters.put("api-version", "2018-02-01");
115+
queryParameters.put("resource", resource);
119116
headers.put("Metadata", "true");
120117
break;
121118
}
122119

123120
switch (id.getIdType()) {
124121
case CLIENT_ID:
125-
queryParameters.put("client_id", Collections.singletonList(id.getUserAssignedId()));
122+
queryParameters.put("client_id", id.getUserAssignedId());
126123
break;
127124
case RESOURCE_ID:
128-
queryParameters.put("mi_res_id", Collections.singletonList(id.getUserAssignedId()));
125+
queryParameters.put("mi_res_id", id.getUserAssignedId());
129126
break;
130127
case OBJECT_ID:
131-
queryParameters.put("object_id", singletonList(id.getUserAssignedId()));
128+
queryParameters.put("object_id", id.getUserAssignedId());
132129
break;
133130
}
134131

135132
return new HttpRequest(HttpMethod.GET, computeUri(endpoint, queryParameters), headers);
136133
}
137134

138-
private String computeUri(String endpoint, Map<String, List<String>> queryParameters) {
135+
private String computeUri(String endpoint, Map<String, String> queryParameters) {
139136
if (queryParameters.isEmpty()) {
140137
return endpoint;
141138
}
142139

143-
String queryString = URLUtils.serializeParameters(queryParameters);
140+
String queryString = StringHelper.serializeQueryParameters(queryParameters);
144141

145142
return endpoint + "?" + queryString;
146143
}

msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/RequestThrottlingTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
package com.microsoft.aad.msal4j;
55

6-
import com.nimbusds.oauth2.sdk.http.HTTPResponse;
76
import org.junit.jupiter.api.AfterEach;
87
import org.junit.jupiter.api.BeforeEach;
98
import org.junit.jupiter.api.Test;
@@ -97,7 +96,7 @@ private PublicClientApplication getClientApplicationMockedWithOneTokenEndpointRe
9796

9897
switch (responseType) {
9998
case RETRY_AFTER_HEADER:
100-
httpResponse.statusCode(HTTPResponse.SC_OK);
99+
httpResponse.statusCode(HttpHelper.HTTP_STATUS_200);
101100
httpResponse.body(TestConfiguration.TOKEN_ENDPOINT_OK_RESPONSE_ID_AND_ACCESS);
102101

103102
headers.put("Retry-After", Arrays.asList(THROTTLE_IN_SEC.toString()));

0 commit comments

Comments
 (0)