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()
            });
        }
Beispiel #4
0
        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);
        }