Skip to content

Commit f993d8a

Browse files
committed
2 parents 8ce31ca + 765852e commit f993d8a

File tree

15 files changed

+232
-64
lines changed

15 files changed

+232
-64
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Quick links:
1616
The library supports the following Java environments:
1717
- Java 8 (or higher)
1818

19-
Current version - 1.19.1
19+
Current version - 1.20.0
2020

2121
You can find the changes for each version in the [change log](https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/main/msal4j-sdk/changelog.txt).
2222

@@ -28,13 +28,13 @@ Find [the latest package in the Maven repository](https://mvnrepository.com/arti
2828
<dependency>
2929
<groupId>com.microsoft.azure</groupId>
3030
<artifactId>msal4j</artifactId>
31-
<version>1.19.1</version>
31+
<version>1.20.0</version>
3232
</dependency>
3333
```
3434
### Gradle
3535

3636
```gradle
37-
implementation group: 'com.microsoft.azure', name: 'com.microsoft.aad.msal4j', version: '1.19.1'
37+
implementation group: 'com.microsoft.azure', name: 'com.microsoft.aad.msal4j', version: '1.20.0'
3838
```
3939

4040
## Usage

changelog.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
Version 1.20.0
2+
=============
3+
- Replace some usage of jackson-databind with azure-json (#918)
4+
- Remove Lombok code generation from most classes (#919, #925)
5+
- Remove some usage of nimbusds-oauth2-oidc-sdk (#927, #928)
6+
- Fix refresh metadata not being set in MI flows (#931)
7+
- Add distinct exception type for JSON parsing errors (#933)
8+
19
Version 1.19.1
210
=============
311
- Update dependencies to avoid CVE-2023-1370 (#914)

msal4j-sdk/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Quick links:
1616
The library supports the following Java environments:
1717
- Java 8 (or higher)
1818

19-
Current version - 1.19.1
19+
Current version - 1.20.0
2020

2121
You can find the changes for each version in the [change log](https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/master/changelog.txt).
2222

@@ -28,13 +28,13 @@ Find [the latest package in the Maven repository](https://mvnrepository.com/arti
2828
<dependency>
2929
<groupId>com.microsoft.azure</groupId>
3030
<artifactId>msal4j</artifactId>
31-
<version>1.19.1</version>
31+
<version>1.20.0</version>
3232
</dependency>
3333
```
3434
### Gradle
3535

3636
```gradle
37-
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.19.1'
37+
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.20.0'
3838
```
3939

4040
## Usage

msal4j-sdk/bnd.bnd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Export-Package: com.microsoft.aad.msal4j;version="1.19.1"
1+
Export-Package: com.microsoft.aad.msal4j;version="1.20.0"
22
Automatic-Module-Name: com.microsoft.aad.msal4j

msal4j-sdk/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.microsoft.azure</groupId>
55
<artifactId>msal4j</artifactId>
6-
<version>1.19.1</version>
6+
<version>1.20.0</version>
77
<packaging>jar</packaging>
88
<name>msal4j</name>
99
<description>

msal4j-sdk/src/integrationtest/java/com.microsoft.aad.msal4j/DeviceCodeIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ void DeviceCodeFlowADFSv2019Test() throws Exception {
7676
IntegrationTestHelper.assertAccessAndIdTokensNotNull(result);
7777
}
7878

79-
@Test()
79+
//TODO: This test is failing intermittently in the pipeline runs for the same commit, but always passes locally. Disabling until we can investigate more.
80+
//@Test()
8081
void DeviceCodeFlowMSATest() throws Exception {
8182

8283
User user = labUserProvider.getMSAUser();

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ public ManagedIdentityResponse handleResponse(
9393

9494
protected ManagedIdentityResponse getSuccessfulResponse(IHttpResponse response) {
9595

96-
ManagedIdentityResponse managedIdentityResponse = JsonHelper.convertJsonStringToJsonSerializableObject(response.body(), ManagedIdentityResponse::fromJson);
96+
ManagedIdentityResponse managedIdentityResponse;
97+
try {
98+
managedIdentityResponse = JsonHelper.convertJsonStringToJsonSerializableObject(response.body(), ManagedIdentityResponse::fromJson);
99+
} catch (MsalJsonParsingException e) {
100+
throw new MsalJsonParsingException(String.format(MsalErrorMessage.MANAGED_IDENTITY_RESPONSE_PARSE_FAILURE, response.statusCode(), e.getMessage()), MsalError.MANAGED_IDENTITY_RESPONSE_PARSE_FAILURE, managedIdentitySourceType);
101+
}
97102

98103
if (managedIdentityResponse == null || managedIdentityResponse.getAccessToken() == null
99104
|| managedIdentityResponse.getAccessToken().isEmpty() || managedIdentityResponse.getExpiresOn() == null
@@ -105,8 +110,13 @@ protected ManagedIdentityResponse getSuccessfulResponse(IHttpResponse response)
105110
}
106111

107112
protected String getMessageFromErrorResponse(IHttpResponse response) {
108-
ManagedIdentityErrorResponse managedIdentityErrorResponse =
109-
JsonHelper.convertJsonToObject(response.body(), ManagedIdentityErrorResponse.class);
113+
114+
ManagedIdentityErrorResponse managedIdentityErrorResponse;
115+
try {
116+
managedIdentityErrorResponse = JsonHelper.convertJsonToObject(response.body(), ManagedIdentityErrorResponse.class);
117+
} catch (MsalJsonParsingException e) {
118+
throw new MsalJsonParsingException(String.format(MsalErrorMessage.MANAGED_IDENTITY_RESPONSE_PARSE_FAILURE, response.statusCode(), e.getMessage()), MsalError.MANAGED_IDENTITY_RESPONSE_PARSE_FAILURE, managedIdentitySourceType);
119+
}
110120

111121
if (managedIdentityErrorResponse == null) {
112122
return MANAGED_IDENTITY_NO_RESPONSE_RECEIVED;

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

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class AcquireTokenByManagedIdentitySupplier extends AuthenticationResultSupplier
1313

1414
private static final Logger LOG = LoggerFactory.getLogger(AcquireTokenByManagedIdentitySupplier.class);
1515

16-
private static final int TWO_HOURS = 2*3600;
16+
private static final int TWO_HOURS = 2 * 3600;
1717

1818
private ManagedIdentityParameters managedIdentityParameters;
1919

@@ -37,49 +37,66 @@ AuthenticationResult execute() throws Exception {
3737
clientApplication.serviceBundle()
3838
);
3939

40-
if (!managedIdentityParameters.forceRefresh) {
41-
LOG.debug("ForceRefresh set to false. Attempting cache lookup");
42-
43-
try {
44-
Set<String> scopes = new HashSet<>();
45-
scopes.add(this.managedIdentityParameters.resource);
46-
SilentParameters parameters = SilentParameters
47-
.builder(scopes)
48-
.tenant(managedIdentityParameters.tenant())
49-
.build();
50-
51-
RequestContext context = new RequestContext(
52-
this.clientApplication,
53-
PublicApi.ACQUIRE_TOKEN_SILENTLY,
54-
parameters);
55-
56-
SilentRequest silentRequest = new SilentRequest(
57-
parameters,
58-
this.clientApplication,
59-
context,
60-
null);
61-
62-
AcquireTokenSilentSupplier supplier = new AcquireTokenSilentSupplier(
63-
this.clientApplication,
64-
silentRequest);
65-
66-
return supplier.execute();
67-
} catch (MsalClientException ex) {
68-
if (ex.errorCode().equals(AuthenticationErrorCode.CACHE_MISS)) {
69-
LOG.debug(String.format("Cache lookup failed: %s", ex.getMessage()));
70-
return fetchNewAccessTokenAndSaveToCache(tokenRequestExecutor);
71-
} else {
72-
LOG.error(String.format("Error occurred while cache lookup: %s", ex.getMessage()));
73-
throw ex;
74-
}
75-
}
40+
CacheRefreshReason cacheRefreshReason = CacheRefreshReason.NOT_APPLICABLE;
41+
42+
if (managedIdentityParameters.forceRefresh) {
43+
LOG.debug("ForceRefresh set to true. Skipping cache lookup and attempting to acquire new token");
44+
return fetchNewAccessTokenAndSaveToCache(tokenRequestExecutor, CacheRefreshReason.FORCE_REFRESH);
7645
}
7746

78-
LOG.info("Skipped looking for an Access Token in the cache because forceRefresh or Claims were set. ");
79-
return fetchNewAccessTokenAndSaveToCache(tokenRequestExecutor);
47+
48+
LOG.debug("ForceRefresh set to false. Attempting cache lookup");
49+
try {
50+
Set<String> scopes = new HashSet<>();
51+
scopes.add(this.managedIdentityParameters.resource);
52+
SilentParameters parameters = SilentParameters
53+
.builder(scopes)
54+
.tenant(managedIdentityParameters.tenant())
55+
.build();
56+
57+
RequestContext context = new RequestContext(
58+
this.clientApplication,
59+
PublicApi.ACQUIRE_TOKEN_SILENTLY,
60+
parameters);
61+
62+
SilentRequest silentRequest = new SilentRequest(
63+
parameters,
64+
this.clientApplication,
65+
context,
66+
null);
67+
68+
AcquireTokenSilentSupplier supplier = new AcquireTokenSilentSupplier(
69+
this.clientApplication,
70+
silentRequest);
71+
72+
AuthenticationResult result = supplier.execute();
73+
cacheRefreshReason = SilentRequestHelper.getCacheRefreshReasonIfApplicable(
74+
parameters,
75+
result,
76+
LOG);
77+
78+
// If the token does not need a refresh, return the cached token
79+
// Else refresh the token if it is either expired, proactively refreshable, or if the claims are passed.
80+
if (cacheRefreshReason == CacheRefreshReason.NOT_APPLICABLE) {
81+
LOG.debug("Returning token from cache");
82+
result.metadata().tokenSource(TokenSource.CACHE);
83+
return result;
84+
} else {
85+
LOG.debug(String.format("Refreshing access token. Cache refresh reason: %s", cacheRefreshReason));
86+
return fetchNewAccessTokenAndSaveToCache(tokenRequestExecutor, cacheRefreshReason);
87+
}
88+
} catch (MsalClientException ex) {
89+
if (ex.errorCode().equals(AuthenticationErrorCode.CACHE_MISS)) {
90+
LOG.debug(String.format("Cache lookup failed: %s", ex.getMessage()));
91+
return fetchNewAccessTokenAndSaveToCache(tokenRequestExecutor, cacheRefreshReason);
92+
} else {
93+
LOG.error(String.format("Error occurred while cache lookup: %s", ex.getMessage()));
94+
throw ex;
95+
}
96+
}
8097
}
8198

82-
private AuthenticationResult fetchNewAccessTokenAndSaveToCache(TokenRequestExecutor tokenRequestExecutor) {
99+
private AuthenticationResult fetchNewAccessTokenAndSaveToCache(TokenRequestExecutor tokenRequestExecutor, CacheRefreshReason cacheRefreshReason) throws Exception {
83100

84101
ManagedIdentityClient managedIdentityClient = new ManagedIdentityClient(msalRequest, tokenRequestExecutor.getServiceBundle());
85102

@@ -91,13 +108,17 @@ private AuthenticationResult fetchNewAccessTokenAndSaveToCache(TokenRequestExecu
91108

92109
AuthenticationResult authenticationResult = createFromManagedIdentityResponse(managedIdentityResponse);
93110
clientApplication.tokenCache.saveTokens(tokenRequestExecutor, authenticationResult, clientApplication.authenticationAuthority.host);
94-
return authenticationResult;
111+
AuthenticationResult result = authenticationResult;
112+
result.metadata().tokenSource(TokenSource.IDENTITY_PROVIDER);
113+
result.metadata().cacheRefreshReason(cacheRefreshReason);
114+
return result;
95115
}
96116

97117
private AuthenticationResult createFromManagedIdentityResponse(ManagedIdentityResponse managedIdentityResponse) {
98118
long expiresOn = Long.parseLong(managedIdentityResponse.expiresOn);
99119
long refreshOn = calculateRefreshOn(expiresOn);
100120
AuthenticationResultMetadata metadata = AuthenticationResultMetadata.builder()
121+
.tokenSource(TokenSource.IDENTITY_PROVIDER)
101122
.refreshOn(refreshOn)
102123
.build();
103124

@@ -111,7 +132,7 @@ private AuthenticationResult createFromManagedIdentityResponse(ManagedIdentityRe
111132
.build();
112133
}
113134

114-
private long calculateRefreshOn(long expiresOn){
135+
private long calculateRefreshOn(long expiresOn) {
115136
long timestampSeconds = System.currentTimeMillis() / 1000;
116137
long expiresIn = expiresOn - timestampSeconds;
117138

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ AuthenticationResult execute() throws Exception {
7373
}
7474
}
7575
}
76+
7677
if (res == null || StringHelper.isBlank(res.accessToken())) {
7778
throw new MsalClientException(AuthenticationErrorMessage.NO_TOKEN_IN_CACHE, AuthenticationErrorCode.CACHE_MISS);
7879
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,17 @@ private JsonHelper() {
3535
static <T> T convertJsonToObject(final String json, final Class<T> tClass) {
3636
try {
3737
return mapper.readValue(json, tClass);
38-
} catch (IOException e) {
39-
throw new MsalClientException(e);
38+
} catch (Exception e) {
39+
throw new MsalJsonParsingException(e.getMessage(), AuthenticationErrorCode.INVALID_JSON);
4040
}
4141
}
4242

4343
//This method is used to convert a JSON string to an object which implements the JsonSerializable interface from com.azure.json
4444
static <T extends JsonSerializable<T>> T convertJsonStringToJsonSerializableObject(String jsonResponse, ReadValueCallback<JsonReader, T> readFunction) {
4545
try (JsonReader jsonReader = JsonProviders.createReader(jsonResponse)) {
4646
return readFunction.read(jsonReader);
47-
} catch (IOException e) {
48-
throw new MsalClientException(e.getMessage(), AuthenticationErrorCode.INVALID_JSON);
4947
} catch (Exception e) {
50-
throw new MsalClientException("Error parsing JSON response: " + e.getMessage(), AuthenticationErrorCode.INVALID_JSON);
48+
throw new MsalJsonParsingException(e.getMessage(), AuthenticationErrorCode.INVALID_JSON);
5149
}
5250
}
5351

0 commit comments

Comments
 (0)