private void DecodeJWT(string token, IAccount account, ref IAuthContext authContext) { JwtPayload jwtPayload = JwtHelpers.DecodeToObject <JwtPayload>(token); if (authContext.AuthType == AuthenticationType.UserProvidedAccessToken) { if (jwtPayload == null) { throw new Exception(string.Format( CultureInfo.CurrentCulture, ErrorConstants.Message.InvalidUserProvidedToken, nameof(AccessToken))); } if (jwtPayload.Exp <= JwtHelpers.ConvertToUnixTimestamp(DateTime.UtcNow + TimeSpan.FromMinutes(Constants.TokenExpirationBufferInMinutes))) { throw new Exception(string.Format( CultureInfo.CurrentCulture, ErrorConstants.Message.ExpiredUserProvidedToken, nameof(AccessToken))); } } authContext.ClientId = jwtPayload?.Appid ?? authContext.ClientId; authContext.Scopes = jwtPayload?.Scp?.Split(' ') ?? jwtPayload?.Roles; authContext.TenantId = jwtPayload?.Tid ?? account?.HomeAccountId?.TenantId; authContext.AppName = jwtPayload?.AppDisplayname; authContext.Account = jwtPayload?.Upn ?? account?.Username; }
public void Decode_ShouldDecodeValidJWTokenPayload() { string validToken = "eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFBMjMyVEVTVCIsImFsZyI6IkhTMjU2In0.eyJmYW1pbHlfbmFtZSI6IkRvZSIsImdpdmVuX25hbWUiOiJKb2huIiwibmFtZSI6IkpvaG4gRG9lIiwib2lkIjoiZTYwMmFkYTctNmVmZC00ZTE4LWE5NzktNjNjMDJiOWYzYzc2Iiwic2NwIjoiVXNlci5SZWFkQmFzaWMuQWxsIiwidGlkIjoiNmJjMTUzMzUtZTJiOC00YTlhLTg2ODMtYTUyYTI2YzhjNTgzIiwidW5pcXVlX25hbWUiOiJqb2huQGRvZS50ZXN0LmNvbSIsInVwbiI6ImpvaG5AZG9lLnRlc3QuY29tIn0.hf9xI5XYBjGec - 4n4_Kxj8Nd2YHBtihdevYhzFxbpXQ"; JwtPayload decodedJwtPayload = JwtHelpers.DecodeToObject <JwtPayload>(validToken.Split('.')[1]); Assert.IsNotNull(decodedJwtPayload, "Unexpected jwt payload decoded."); Assert.IsNotNull(decodedJwtPayload.Oid, "Unexpected oid set decoded."); }
/// <summary> /// Creats a <see cref="GraphUserAccount"/> object from a JWT access token. /// </summary> /// <param name="jwtAccessToken">JWT token to parse.</param> /// <returns></returns> private GraphUserAccount GetGraphUserAccount(string jwtAccessToken) { if (string.IsNullOrEmpty(jwtAccessToken)) { return(null); } // Get jwt payload string[] jwtSegments = jwtAccessToken.Split('.'); string payloadSegmant = jwtSegments.Count() == 1 ? jwtSegments.First() : jwtSegments[1]; JwtPayload jwtPayload = JwtHelpers.DecodeToObject <JwtPayload>(payloadSegmant); return(new GraphUserAccount() { Email = jwtPayload.Upn, ObjectId = jwtPayload.Oid.ToString(), TenantId = jwtPayload.Oid.ToString() }); }
protected override void ProcessRecord() { base.ProcessRecord(); AuthConfig authConfig = new AuthConfig { TenantId = TenantId }; CancellationToken cancellationToken = CancellationToken.None; if (ParameterSetName == Constants.UserParameterSet) { // 2 mins timeout. 1 min < HTTP timeout. TimeSpan authTimeout = new TimeSpan(0, 0, Constants.MaxDeviceCodeTimeOut); CancellationTokenSource cts = new CancellationTokenSource(authTimeout); cancellationToken = cts.Token; authConfig.AuthType = AuthenticationType.Delegated; authConfig.Scopes = Scopes ?? new string[] { "User.Read" }; } else { authConfig.AuthType = AuthenticationType.AppOnly; authConfig.ClientId = ClientId; authConfig.CertificateThumbprint = CertificateThumbprint; authConfig.CertificateName = CertificateName; } try { // Gets a static instance of IAuthenticationProvider when the client app hasn't changed. IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(authConfig); IClientApplicationBase clientApplication = null; if (ParameterSetName == Constants.UserParameterSet) { clientApplication = (authProvider as DeviceCodeProvider).ClientApplication; } else { clientApplication = (authProvider as ClientCredentialProvider).ClientApplication; } // Incremental scope consent without re-instanciating the auth provider. We will use a static instance. GraphRequestContext graphRequestContext = new GraphRequestContext(); graphRequestContext.CancellationToken = cancellationToken; graphRequestContext.MiddlewareOptions = new Dictionary <string, IMiddlewareOption> { { typeof(AuthenticationHandlerOption).ToString(), new AuthenticationHandlerOption { AuthenticationProviderOption = new AuthenticationProviderOption { Scopes = authConfig.Scopes, ForceRefresh = ForceRefresh } } } }; // Trigger consent. HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me"); httpRequestMessage.Properties.Add(typeof(GraphRequestContext).ToString(), graphRequestContext); authProvider.AuthenticateRequestAsync(httpRequestMessage).GetAwaiter().GetResult(); var accounts = clientApplication.GetAccountsAsync().GetAwaiter().GetResult(); var account = accounts.FirstOrDefault(); JwtPayload jwtPayload = JwtHelpers.DecodeToObject <JwtPayload>(httpRequestMessage.Headers.Authorization?.Parameter); authConfig.Scopes = jwtPayload?.Scp?.Split(' ') ?? jwtPayload?.Roles; authConfig.TenantId = jwtPayload?.Tid ?? account?.HomeAccountId?.TenantId; authConfig.AppName = jwtPayload?.AppDisplayname; authConfig.Account = jwtPayload?.Upn ?? account?.Username; // Save auth config to session state. SessionState.PSVariable.Set(Constants.GraphAuthConfigId, authConfig); } catch (AuthenticationException authEx) { if ((authEx.InnerException is TaskCanceledException) && cancellationToken.IsCancellationRequested) { throw new Exception($"Device code terminal timed-out after {Constants.MaxDeviceCodeTimeOut} seconds. Please try again."); } else { throw authEx.InnerException ?? authEx; } } catch (Exception ex) { throw ex.InnerException ?? ex; } WriteObject("Welcome To Microsoft Graph!"); }
public void Decode_ShouldThrowExceptionWhenInvalidJWTokenPayloadIsSet() { string validToken = "eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFBMjMyVEVTVCIsImFsZyI6IkhTMjU2In0.eyJmYW1pbHlfbmFtZSI6IkRvZSIsImdpdmVuX25hbWUiOiJKb2huIiwibmFtZSI6IkpvaG4gRG9lIiwib2lkIjoiZTYwMmFkYTctNmVmZC00ZTE4LWE5NzktNjNjMDJiOWYzYzc2Iiwic2NwIjoiVXNlci5SZWFkQmFzaWMuQWxsIiwidGlkIjoiNmJjMTUzMzUtZTJiOC00YTlhLTg2ODMtYTUyYTI2YzhjNTgzIiwidW5pcXVlX25hbWUiOiJqb2huQGRvZS50ZXN0LmNvbSIsInVwbiI6ImpvaG5AZG9lLnRlc3QuY29tIn0.hf9xI5XYBjGec - 4n4_Kxj8Nd2YHBtihdevYhzFxbpXQ"; AuthenticationException exception = Assert.ThrowsException <AuthenticationException>(() => JwtHelpers.DecodeToObject <JwtPayload>(validToken)); Assert.AreEqual(exception.Error.Code, ErrorConstants.Codes.InvalidJWT); Assert.AreEqual(exception.Error.Message, ErrorConstants.Message.InvalidJWT); }