diff --git a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/MSIToken.java b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/MSIToken.java index 14245e0e2026c..7601c6d536b5c 100644 --- a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/MSIToken.java +++ b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/MSIToken.java @@ -35,15 +35,11 @@ public final class MSIToken extends AccessToken { * @param token the token string. * @param expiresOn the expiration time. */ - public MSIToken(String token, OffsetDateTime expiresOn) { - super(token, expiresOn); - } - @JsonCreator - private MSIToken( + public MSIToken( @JsonProperty(value = "access_token") String token, @JsonProperty(value = "expires_on") String expiresOn) { - this(token, EPOCH.plusSeconds(parseDateToEpochSeconds(expiresOn))); + super(token, EPOCH.plusSeconds(parseDateToEpochSeconds(expiresOn))); this.accessToken = token; this.expiresOn = expiresOn; } @@ -53,21 +49,13 @@ public String getToken() { return accessToken; } - @Override - public OffsetDateTime getExpiresAt() { - return EPOCH.plusSeconds(parseDateToEpochSeconds(this.expiresOn)); - } - - @Override - public boolean isExpired() { - OffsetDateTime now = OffsetDateTime.now(); - OffsetDateTime expireOn = EPOCH.plusSeconds(parseDateToEpochSeconds(this.expiresOn)); - return now.plusMinutes(5).isAfter(expireOn); - } - private static Long parseDateToEpochSeconds(String dateTime) { ClientLogger logger = new ClientLogger(MSIToken.class); - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss XXX"); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy H:mm:ss XXX"); + // This is the format for app service on Windows as of API version 2017-09-01. + // The format is changed to Unix timestamp in 2019-08-01 but this API version + // has not been deployed to Linux app services. + DateTimeFormatter dtfWindows = DateTimeFormatter.ofPattern("M/d/yyyy K:mm:ss a XXX"); try { return Long.parseLong(dateTime); } catch (NumberFormatException e) { @@ -75,7 +63,13 @@ private static Long parseDateToEpochSeconds(String dateTime) { } try { - return Instant.from(dtf.parse(dateTime)).toEpochMilli() / 1000L; + return Instant.from(dtf.parse(dateTime)).getEpochSecond(); + } catch (DateTimeParseException e) { + logger.error(e.getMessage()); + } + + try { + return Instant.from(dtfWindows.parse(dateTime)).getEpochSecond(); } catch (DateTimeParseException e) { logger.error(e.getMessage()); } diff --git a/sdk/identity/azure-identity/src/main/java/module-info.java b/sdk/identity/azure-identity/src/main/java/module-info.java index 7ad34c6e4e294..30acdcb099c13 100644 --- a/sdk/identity/azure-identity/src/main/java/module-info.java +++ b/sdk/identity/azure-identity/src/main/java/module-info.java @@ -14,4 +14,6 @@ requires org.reactivestreams; exports com.azure.identity; + + opens com.azure.identity.implementation to com.fasterxml.jackson.databind; } diff --git a/sdk/identity/azure-identity/src/test/java/com/azure/identity/implementation/MSITokenTests.java b/sdk/identity/azure-identity/src/test/java/com/azure/identity/implementation/MSITokenTests.java new file mode 100644 index 0000000000000..3284fc197e46b --- /dev/null +++ b/sdk/identity/azure-identity/src/test/java/com/azure/identity/implementation/MSITokenTests.java @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.identity.implementation; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +public class MSITokenTests { + private OffsetDateTime expected = OffsetDateTime.of(2020, 1, 10, 15, 1, 28, 0, ZoneOffset.UTC); + + @Test + public void canParseLong() { + MSIToken token = new MSIToken("fake_token", "1578668608"); + Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond()); + } + + @Test + public void canParseDateTime24Hr() { + MSIToken token = new MSIToken("fake_token", "01/10/2020 15:03:28 +00:00"); + Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond()); + } + + @Test + public void canParseDateTime12Hr() { + MSIToken token = new MSIToken("fake_token", "1/10/2020 3:03:28 PM +00:00"); + Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond()); + + token = new MSIToken("fake_token", "12/20/2019 4:58:20 AM +00:00"); + expected = OffsetDateTime.of(2019, 12, 20, 4, 56, 20, 0, ZoneOffset.UTC); + Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond()); + + token = new MSIToken("fake_token", "1/1/2020 0:00:00 PM +00:00"); + expected = OffsetDateTime.of(2020, 1, 1, 11, 58, 0, 0, ZoneOffset.UTC); + Assert.assertEquals(expected.toEpochSecond(), token.getExpiresAt().toEpochSecond()); + } +}