private async Task <AuthenticationResult> GetNewAccessTokenAsync(AuthenticationProviderOption msalAuthProviderOption)
        {
            AuthenticationResult authenticationResult = null;
            int retryCount = 0;

            do
            {
                try
                {
                    if (!string.IsNullOrEmpty(msalAuthProviderOption.UserAccount?.Email))
                    {
                        authenticationResult = await ClientApplication.AcquireTokenByIntegratedWindowsAuth(msalAuthProviderOption.Scopes)
                                               .WithUsername(msalAuthProviderOption.UserAccount.Email)
                                               .ExecuteAsync();
                    }
                    else
                    {
                        authenticationResult = await ClientApplication.AcquireTokenByIntegratedWindowsAuth(Scopes)
                                               .ExecuteAsync();
                    }
                    break;
                }
                catch (MsalServiceException serviceException)
                {
                    if (serviceException.ErrorCode == ErrorConstants.Codes.TemporarilyUnavailable)
                    {
                        TimeSpan delay = this.GetRetryAfter(serviceException);
                        retryCount++;
                        // pause execution
                        await Task.Delay(delay);
                    }
                    else
                    {
                        throw new AuthenticationException(
                                  new Error
                        {
                            Code    = ErrorConstants.Codes.GeneralException,
                            Message = ErrorConstants.Message.UnexpectedMsalException
                        },
                                  serviceException);
                    }
                }
                catch (Exception exception)
                {
                    throw new AuthenticationException(
                              new Error
                    {
                        Code    = ErrorConstants.Codes.GeneralException,
                        Message = ErrorConstants.Message.UnexpectedException
                    },
                              exception);
                }
            } while (retryCount < msalAuthProviderOption.MaxRetry);

            return(authenticationResult);
        }
Esempio n. 2
0
        /// <summary>
        /// Sets <see cref="UserAssertion"/> for this request.
        /// This should only be used with <see cref="OnBehalfOfProvider"/>.
        /// </summary>
        /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param>
        /// <param name="userAssertion">A <see cref="UserAssertion"/> for the user.</param>
        public static T WithUserAssertion <T>(this T baseRequest, UserAssertion userAssertion) where T : IBaseRequest
        {
            string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString();
            AuthenticationHandlerOption  authHandlerOptions     = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption;
            AuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as AuthenticationProviderOption ?? new AuthenticationProviderOption();

            msalAuthProviderOption.UserAssertion = userAssertion;

            authHandlerOptions.AuthenticationProviderOption     = msalAuthProviderOption;
            baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions;

            return(baseRequest);
        }
Esempio n. 3
0
        /// <summary>
        /// Sets Microsoft Graph's scopes that will be used by <see cref="IAuthenticationProvider"/> to authenticate this request
        /// and can be used to perform incremental scope consent.
        /// This only works with the default authentication handler and default set of Microsoft graph authentication providers.
        /// If you use a custom authentication handler or authentication provider, you have to handle it's retrieval in your implementation.
        /// </summary>
        /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param>
        /// <param name="scopes">Microsoft graph scopes used to authenticate this request.</param>
        public static T WithScopes <T>(this T baseRequest, string[] scopes) where T : IBaseRequest
        {
            string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString();
            AuthenticationHandlerOption  authHandlerOptions     = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption;
            AuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as AuthenticationProviderOption ?? new AuthenticationProviderOption();

            msalAuthProviderOption.Scopes = scopes;

            authHandlerOptions.AuthenticationProviderOption     = msalAuthProviderOption;
            baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions;

            return(baseRequest);
        }
Esempio n. 4
0
        /// <summary>
        /// Sets MSAL's force refresh flag to <see cref="IAuthenticationProvider"/> for this request. If set to true, <see cref="IAuthenticationProvider"/> will refresh existing access token in cahce.
        /// This defaults to false if not set.
        /// </summary>
        /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param>
        /// <param name="forceRefresh">A <see cref="bool"/> flag to determine whether refresh access token or not.</param>
        public static T WithForceRefresh <T>(this T baseRequest, bool forceRefresh) where T : IBaseRequest
        {
            string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString();
            AuthenticationHandlerOption  authHandlerOptions     = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption;
            AuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as AuthenticationProviderOption ?? new AuthenticationProviderOption();

            msalAuthProviderOption.ForceRefresh = forceRefresh;

            authHandlerOptions.AuthenticationProviderOption     = msalAuthProviderOption;
            baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions;

            return(baseRequest);
        }
Esempio n. 5
0
        /// <summary>
        /// Adds an authentication header to the incoming request by checking the application's <see cref="TokenCache"/>
        /// for an unexpired access token. If a token is not found or expired, it gets a new one.
        /// </summary>
        /// <param name="httpRequestMessage">A <see cref="HttpRequestMessage"/> to authenticate</param>
        public async Task AuthenticateRequestAsync(HttpRequestMessage httpRequestMessage)
        {
            AuthenticationProviderOption msalAuthProviderOption = httpRequestMessage.GetMsalAuthProviderOption();
            int retryCount = 0;

            do
            {
                try
                {
                    AuthenticationResult authenticationResult = await ClientApplication.AcquireTokenForClient(new string[] { AuthConstants.DefaultScopeUrl })
                                                                .WithForceRefresh(msalAuthProviderOption.ForceRefresh)
                                                                .ExecuteAsync();

                    if (!string.IsNullOrEmpty(authenticationResult?.AccessToken))
                    {
                        httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue(CoreConstants.Headers.Bearer, authenticationResult.AccessToken);
                    }
                    break;
                }
                catch (MsalServiceException serviceException)
                {
                    if (serviceException.ErrorCode == ErrorConstants.Codes.TemporarilyUnavailable)
                    {
                        TimeSpan delay = this.GetRetryAfter(serviceException);
                        retryCount++;
                        // pause execution
                        await Task.Delay(delay);
                    }
                    else
                    {
                        throw new AuthenticationException(
                                  new Error
                        {
                            Code    = ErrorConstants.Codes.GeneralException,
                            Message = ErrorConstants.Message.UnexpectedMsalException
                        },
                                  serviceException);
                    }
                }
                catch (Exception exception)
                {
                    throw new AuthenticationException(
                              new Error
                    {
                        Code    = ErrorConstants.Codes.GeneralException,
                        Message = ErrorConstants.Message.UnexpectedException
                    },
                              exception);
                }
            } while (retryCount < msalAuthProviderOption.MaxRetry);
        }
Esempio n. 6
0
        internal static AuthenticationProviderOption GetMsalAuthProviderOption(this HttpRequestMessage httpRequestMessage)
        {
            AuthenticationHandlerOption  authHandlerOption            = httpRequestMessage.GetMiddlewareOption <AuthenticationHandlerOption>();
            AuthenticationProviderOption authenticationProviderOption = authHandlerOption?.AuthenticationProviderOption as AuthenticationProviderOption ?? new AuthenticationProviderOption();

            // copy the claims and scopes information
            if (authHandlerOption?.AuthenticationProviderOption is ICaeAuthenticationProviderOption caeAuthenticationProviderOption)
            {
                authenticationProviderOption.Claims = caeAuthenticationProviderOption.Claims;
                authenticationProviderOption.Scopes = caeAuthenticationProviderOption.Scopes;
            }

            return(authenticationProviderOption);
        }
Esempio n. 7
0
        private async Task <AuthenticationResult> GetNewAccessTokenAsync(AuthenticationProviderOption msalAuthProviderOption)
        {
            AuthenticationResult authenticationResult = null;
            int retryCount = 0;

            do
            {
                try
                {
                    authenticationResult = await ClientApplication.AcquireTokenOnBehalfOf(msalAuthProviderOption.Scopes, msalAuthProviderOption.UserAssertion)
                                           .WithAuthority(ClientApplication.Authority)
                                           .ExecuteAsync();

                    break;
                }
                catch (MsalServiceException serviceException)
                {
                    if (serviceException.ErrorCode == ErrorConstants.Codes.TemporarilyUnavailable)
                    {
                        TimeSpan delay = this.GetRetryAfter(serviceException);
                        retryCount++;
                        // pause execution
                        await Task.Delay(delay);
                    }
                    else
                    {
                        throw new AuthenticationException(
                                  new Error
                        {
                            Code    = ErrorConstants.Codes.GeneralException,
                            Message = ErrorConstants.Message.UnexpectedMsalException
                        },
                                  serviceException);
                    }
                }
                catch (Exception exception)
                {
                    throw new AuthenticationException(
                              new Error
                    {
                        Code    = ErrorConstants.Codes.GeneralException,
                        Message = ErrorConstants.Message.UnexpectedException
                    },
                              exception);
                }
            } while (retryCount < msalAuthProviderOption.MaxRetry);

            return(authenticationResult);
        }
Esempio n. 8
0
        /// <summary>
        /// Sets a username (email) and password of an Azure AD account to authenticate.
        /// This should only be used with <see cref="UsernamePasswordProvider"/>.
        /// This provider is NOT RECOMMENDED because it exposes the users password.
        /// We recommend you use <see cref="IntegratedWindowsAuthenticationProvider"/> instead.
        /// </summary>
        /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param>
        /// <param name="email">Email address of the user to authenticate.</param>
        /// <param name="password">Password of the user to authenticate.</param>
        public static T WithUsernamePassword <T>(this T baseRequest, string email, SecureString password) where T : IBaseRequest
        {
            string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString();
            AuthenticationHandlerOption  authHandlerOptions     = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption;
            AuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as AuthenticationProviderOption ?? new AuthenticationProviderOption();

            msalAuthProviderOption.Password    = password;
            msalAuthProviderOption.UserAccount = new GraphUserAccount {
                Email = email
            };

            authHandlerOptions.AuthenticationProviderOption     = msalAuthProviderOption;
            baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions;

            return(baseRequest);
        }
        /// <summary>
        /// Adds an authentication header to the incoming request by checking the application's <see cref="TokenCache"/>
        /// for an unexpired access token. If a token is not found or expired, it gets a new one.
        /// </summary>
        /// <param name="httpRequestMessage">A <see cref="HttpRequestMessage"/> to authenticate.</param>
        public async Task AuthenticateRequestAsync(HttpRequestMessage httpRequestMessage)
        {
            AuthenticationProviderOption msalAuthProviderOption = httpRequestMessage.GetMsalAuthProviderOption();

            msalAuthProviderOption.Scopes = msalAuthProviderOption.Scopes ?? Scopes.ToArray();

            AuthenticationResult authenticationResult = await ClientApplication.GetAccessTokenSilentAsync(msalAuthProviderOption);

            if (authenticationResult == null)
            {
                authenticationResult = await GetNewAccessTokenAsync(msalAuthProviderOption);
            }

            if (!string.IsNullOrEmpty(authenticationResult.AccessToken))
            {
                httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue(CoreConstants.Headers.Bearer, authenticationResult.AccessToken);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Adds an authentication header to the incoming request by checking the application's <see cref="TokenCache"/>
        /// for an unexpired access token.
        /// If an access token doesn't exist, it will throw a <see cref="AuthenticationException"/>
        /// and the web app must handle this and perform a challange.
        /// </summary>
        /// <param name="httpRequestMessage">A <see cref="HttpRequestMessage"/> to authenticate.</param>
        public async Task AuthenticateRequestAsync(HttpRequestMessage httpRequestMessage)
        {
            AuthenticationProviderOption msalAuthProviderOption = httpRequestMessage.GetMsalAuthProviderOption();

            msalAuthProviderOption.Scopes = msalAuthProviderOption.Scopes ?? Scopes.ToArray();

            AuthenticationResult authenticationResult = await ClientApplication.GetAccessTokenSilentAsync(msalAuthProviderOption);

            if (string.IsNullOrEmpty(authenticationResult?.AccessToken))
            {
                throw new AuthenticationException(
                          new Error
                {
                    Code    = ErrorConstants.Codes.AuthenticationChallengeRequired,
                    Message = ErrorConstants.Message.AuthenticationChallengeRequired
                });
            }

            httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue(CoreConstants.Headers.Bearer, authenticationResult.AccessToken);
        }
Esempio n. 11
0
        private async Task <AuthenticationResult> GetNewAccessTokenAsync(IAccount account, AuthenticationProviderOption msalAuthProviderOption)
        {
            AuthenticationResult authenticationResult = null;

            int    retryCount          = 0;
            string extraQueryParameter = null;

            do
            {
                try
                {
                    var builder = ClientApplication.AcquireTokenInteractive(msalAuthProviderOption.Scopes)
                                  .WithAccount(account)
                                  .WithPrompt(Prompt)
                                  .WithExtraQueryParameters(extraQueryParameter)
                                  .WithExtraScopesToConsent(null)
                                  .WithAuthority(ClientApplication.Authority);
#if NET45
                    if (ParentWindow != null)
                    {
                        builder = builder.WithParentActivityOrWindow(ParentWindow);
                    }
                    else
                    {
                        builder = builder.WithParentActivityOrWindow(ParentPointer);
                    }
#elif NETSTANDARD1_3
                    builder = builder.WithParentActivityOrWindow(Parent);
#endif
                    authenticationResult = await builder.ExecuteAsync();

                    break;
                }
                catch (MsalServiceException serviceException)
                {
                    if (serviceException.ErrorCode == ErrorConstants.Codes.TemporarilyUnavailable)
                    {
                        TimeSpan delay = this.GetRetryAfter(serviceException);
                        retryCount++;
                        // pause execution
                        await Task.Delay(delay);
                    }
                    else if (serviceException.Claims != null)
                    {
                        extraQueryParameter = $"claims={serviceException.Claims}";
                        retryCount++;
                    }
                    else
                    {
                        throw new AuthenticationException(
                                  new Error
                        {
                            Code    = ErrorConstants.Codes.GeneralException,
                            Message = ErrorConstants.Message.UnexpectedMsalException
                        },
                                  serviceException);
                    }
                }
                catch (Exception exception)
                {
                    throw new AuthenticationException(
                              new Error
                    {
                        Code    = ErrorConstants.Codes.GeneralException,
                        Message = ErrorConstants.Message.UnexpectedException
                    },
                              exception);
                }
            } while (retryCount < msalAuthProviderOption.MaxRetry);


            return(authenticationResult);
        }
Esempio n. 12
0
        private async Task <AuthenticationResult> GetNewAccessTokenAsync(CancellationToken cancellationToken, AuthenticationProviderOption msalAuthProviderOption)
        {
            AuthenticationResult authenticationResult = null;
            int    retryCount          = 0;
            string extraQueryParameter = null;

            do
            {
                try
                {
                    AcquireTokenWithDeviceCodeParameterBuilder parameterBuilder = ClientApplication
                                                                                  .AcquireTokenWithDeviceCode(msalAuthProviderOption.Scopes, DeviceCodeResultCallback)
                                                                                  .WithExtraQueryParameters(extraQueryParameter);

                    if (!string.IsNullOrEmpty(msalAuthProviderOption.Claims))
                    {
                        parameterBuilder.WithClaims(msalAuthProviderOption.Claims);
                    }

                    authenticationResult = await parameterBuilder.ExecuteAsync(cancellationToken);

                    break;
                }
                catch (MsalServiceException serviceException)
                {
                    if (serviceException.ErrorCode == ErrorConstants.Codes.TemporarilyUnavailable)
                    {
                        TimeSpan delay = this.GetRetryAfter(serviceException);
                        retryCount++;
                        // pause execution
                        await Task.Delay(delay);
                    }
                    else if (serviceException.Claims != null)
                    {
                        extraQueryParameter = $"claims={serviceException.Claims}";
                        retryCount++;
                    }
                    else
                    {
                        throw new AuthenticationException(
                                  new Error
                        {
                            Code    = ErrorConstants.Codes.GeneralException,
                            Message = ErrorConstants.Message.UnexpectedMsalException
                        },
                                  serviceException);
                    }
                }
                catch (Exception exception)
                {
                    throw new AuthenticationException(
                              new Error
                    {
                        Code    = ErrorConstants.Codes.GeneralException,
                        Message = ErrorConstants.Message.UnexpectedException
                    },
                              exception);
                }
            } while (retryCount < msalAuthProviderOption.MaxRetry);

            return(authenticationResult);
        }