Skip to content

Commit a693fae

Browse files
committed
Add token validation.
1 parent fcae286 commit a693fae

File tree

5 files changed

+33
-5
lines changed

5 files changed

+33
-5
lines changed

src/Authentication/Authentication/Cmdlets/ConnectGraph.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,23 @@ private void ThrowParameterError(string parameterName)
239239
private void DecodeJWT(string token, IAccount account, ref IAuthContext authContext)
240240
{
241241
JwtPayload jwtPayload = JwtHelpers.DecodeToObject<JwtPayload>(token);
242-
if (jwtPayload == null && authContext.AuthType == AuthenticationType.UserProvidedAccessToken)
242+
if (authContext.AuthType == AuthenticationType.UserProvidedAccessToken)
243243
{
244-
throw new Exception(string.Format(
245-
CultureInfo.CurrentCulture,
246-
ErrorConstants.Message.InvalidUserProvidedToken,
247-
nameof(AccessToken)));
244+
if (jwtPayload == null)
245+
{
246+
throw new Exception(string.Format(
247+
CultureInfo.CurrentCulture,
248+
ErrorConstants.Message.InvalidUserProvidedToken,
249+
nameof(AccessToken)));
250+
}
251+
252+
if (jwtPayload.Exp <= JwtHelpers.ConvertToUnixTimestamp(DateTime.UtcNow + TimeSpan.FromMinutes(Constants.TokenExpirationBufferInMinutes)))
253+
{
254+
throw new Exception(string.Format(
255+
CultureInfo.CurrentCulture,
256+
ErrorConstants.Message.ExpiredUserProvidedToken,
257+
nameof(AccessToken)));
258+
}
248259
}
249260

250261
authContext.ClientId = jwtPayload?.Appid ?? authContext.ClientId;

src/Authentication/Authentication/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ public static class Constants
1818
internal const string ProfileDescription = "A snapshot of the Microsoft Graph {0} API for {1} cloud.";
1919
internal const string TokenCacheServiceName = "com.microsoft.graph.powershell.sdkcache";
2020
internal const string DefaultProfile = "v1.0-beta";
21+
internal const int TokenExpirationBufferInMinutes = 5;
2122
}
2223
}

src/Authentication/Authentication/ErrorConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ internal static class Message
2323
internal const string MacKeyChainFailed = "{0} failed with result code {1}.";
2424
internal const string DeviceCodeTimeout = "Device code terminal timed-out after {0} seconds. Please try again.";
2525
internal const string InvalidUserProvidedToken = "The provided access token is invalid. Set a valid access token to `-{0}` parameter and try again.";
26+
internal const string ExpiredUserProvidedToken = "The provided access token has expired. Set a valid access token to `-{0}` parameter and try again.";
2627
}
2728
}
2829
}

src/Authentication/Authentication/Helpers/JwtHelpers.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,17 @@ internal static T DecodeToObject<T>(string jwtString)
5959
}, ex);
6060
}
6161
}
62+
63+
/// <summary>
64+
/// Converts a DateTime to Unix timestamp in seconds past epoch.
65+
/// </summary>
66+
/// <param name="time">A <see cref="DateTime"/> to convert.</param>
67+
/// <returns>Unix timestamp.</returns>
68+
internal static long ConvertToUnixTimestamp(DateTime time)
69+
{
70+
DateTime epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
71+
TimeSpan timeDiff = time - epochTime;
72+
return (long)timeDiff.TotalSeconds;
73+
}
6274
}
6375
}

src/Authentication/Authentication/Models/JwtPayload.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ namespace Microsoft.Graph.PowerShell.Authentication.Models
88
using Newtonsoft.Json;
99
internal partial class JwtPayload
1010
{
11+
[JsonProperty("exp")]
12+
public long Exp { get; set; }
13+
1114
[JsonProperty("aud")]
1215
public Uri Aud { get; set; }
1316

0 commit comments

Comments
 (0)