public async Task <ActionResult> Authorize()
        {
            ConfidentialClientApplicationBuilder clientBuilder = ConfidentialClientApplicationBuilder.Create(AzureADClientId);

            clientBuilder.WithClientSecret(AzureADClientSecret);
            clientBuilder.WithRedirectUri(loginRedirectUri.ToString());
            clientBuilder.WithAuthority(AzureADAuthority);

            ConfidentialClientApplication clientApp = (ConfidentialClientApplication)clientBuilder.Build();

            string[] sassScopes = $"{SaaSScopes}".Split(new[] { ' ' });
            try
            {
                // Get and save the token.
                var authResultBuilder = clientApp.AcquireTokenByAuthorizationCode(
                    sassScopes,
                    Request.Params["code"]
                    );

                var authResult = await authResultBuilder.ExecuteAsync();

                var activation = await _assignedUserService.Activate($"{SaaSAPI}/{OfferID}", authResult.AccessToken);

                ViewBag.accountName = authResult.Account.Username;
                return(View(activation));
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.ToString());
            }

            return(View());
        }
        public async Task <ActionResult> Authorize()
        {
            ConfidentialClientApplicationBuilder clientBuilder = ConfidentialClientApplicationBuilder.Create(_azureAdOptions.ClientId);

            clientBuilder.WithClientSecret(_azureAdOptions.ClientSecret);
            clientBuilder.WithRedirectUri(LoginRedirectUri.ToString());
            clientBuilder.WithAuthority(_azureAdOptions.Authority);

            ConfidentialClientApplication clientApp = (ConfidentialClientApplication)clientBuilder.Build();

            string[] sassScopes = $"{_azureAdOptions.SaaSScopes}".Split(new[] { ' ' });

            var authResultBuilder = clientApp.AcquireTokenByAuthorizationCode(
                sassScopes,
                HttpContext.Request.Query["code"].ToString()
                );

            try
            {
                var authResult = await authResultBuilder.ExecuteAsync();

                var offer      = Offers.ContosoAppOffer;
                var activation = await _assignedUserService.Activate($"{_azureAdOptions.SaaSAPI}/{offer.OfferID}", authResult.AccessToken);

                ViewBag.Message = JsonConvert.SerializeObject(
                    new { status = "success", activation = activation, accountName = authResult.Account.Username });
            }
            catch (Exception e)
            {
                ViewBag.Message = JsonConvert.SerializeObject(new { status = "failure", error = e.Message });
            }

            return(View());
        }
        private async Task InitializeAsync()
        {
            ConfidentialClientApplicationBuilder confClientBuilder = ConfidentialClientApplicationBuilder.Create(_options.ClientId).WithAuthority(_options.AuthorityHost.AbsoluteUri, _options.TenantId).WithHttpClientFactory(new HttpPipelineClientFactory(_options.Pipeline.HttpPipeline));

            if (_options.Secret != null)
            {
                confClientBuilder.WithClientSecret(_options.Secret);
            }

            if (_options.CertificateProvider != null)
            {
                X509Certificate2 clientCertificate = await _options.CertificateProvider.GetCertificateAsync(true, default).ConfigureAwait(false);

                confClientBuilder.WithCertificate(clientCertificate);
            }

            _client = confClientBuilder.Build();

            if (_options.AttachSharedCache)
            {
                StorageCreationProperties storageProperties = new StorageCreationPropertiesBuilder(Constants.DefaultMsalTokenCacheName, Constants.DefaultMsalTokenCacheDirectory, _options.ClientId)
                                                              .WithMacKeyChain(Constants.DefaultMsalTokenCacheKeychainService, Constants.DefaultMsalTokenCacheKeychainAccount)
                                                              .WithLinuxKeyring(Constants.DefaultMsalTokenCacheKeyringSchema, Constants.DefaultMsalTokenCacheKeyringCollection, Constants.DefaultMsalTokenCacheKeyringLabel, Constants.DefaultMsaltokenCacheKeyringAttribute1, Constants.DefaultMsaltokenCacheKeyringAttribute2)
                                                              .Build();

                MsalCacheHelper cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

                cacheHelper.RegisterCache(_client.UserTokenCache);
            }
        }
Example #4
0
        protected override async ValueTask <IConfidentialClientApplication> CreateClientAsync(bool async, CancellationToken cancellationToken)
        {
            ConfidentialClientApplicationBuilder confClientBuilder = ConfidentialClientApplicationBuilder.Create(ClientId)
                                                                     .WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, TenantId)
                                                                     .WithHttpClientFactory(new HttpPipelineClientFactory(Pipeline.HttpPipeline))
                                                                     .WithLogging(AzureIdentityEventSource.Singleton.LogMsal, enablePiiLogging: LogPII);

            if (_clientSecret != null)
            {
                confClientBuilder.WithClientSecret(_clientSecret);
            }

            if (_certificateProvider != null)
            {
                X509Certificate2 clientCertificate = await _certificateProvider.GetCertificateAsync(async, cancellationToken).ConfigureAwait(false);

                confClientBuilder.WithCertificate(clientCertificate);
            }

            if (RegionalAuthority.HasValue)
            {
                confClientBuilder.WithAzureRegion(RegionalAuthority.Value.ToString());
            }

            return(confClientBuilder.Build());
        }
Example #5
0
        /// <summary>
        /// Gets IdToken from implicit flow and sends it to main add-in window.
        /// </summary>
        /// <returns>The default view.</returns>
        public async Task <ActionResult> Authorize()
        {
            ConfidentialClientApplicationBuilder clientBuilder = ConfidentialClientApplicationBuilder.Create(Settings.AzureADClientId);

            clientBuilder.WithClientSecret(Settings.AzureADClientSecret);
            clientBuilder.WithRedirectUri(loginRedirectUri.ToString());
            clientBuilder.WithAuthority(Settings.AzureADAuthority);

            ConfidentialClientApplication clientApp = (ConfidentialClientApplication)clientBuilder.Build();

            string[] graphScopes = { "Files.Read.All", "User.Read" };

            // Get and save the token.
            var authResultBuilder = clientApp.AcquireTokenByAuthorizationCode(
                graphScopes,
                Request.Params["code"]                   // The auth 'code' parameter from the Azure redirect.
                );

            try
            {
                var authResult = await authResultBuilder.ExecuteAsync();

                ViewBag.AccessToken = authResult.AccessToken;
            }
            catch (Exception e)
            {
                ViewBag.Error = e.Message;
            }

            return(View());
        }
        public HttpResponseMessage Token(Token body)
        {
            if (string.IsNullOrEmpty(body.UserToken))
            {
                return(SendErrorToClient(HttpStatusCode.InternalServerError, null, "No token provided"));
            }

            UserAssertion userAssertion = new UserAssertion(body.UserToken);

            // Get the access token for MS Graph.
            ConfidentialClientApplicationBuilder b = ConfidentialClientApplicationBuilder.Create(ConfigurationManager.AppSettings["ida:ClientID"]);

            b.WithClientSecret(ConfigurationManager.AppSettings["ida:Password"]).WithRedirectUri(ConfigurationManager.AppSettings["ida:RedirectUri"]);
            IConfidentialClientApplication cca = b.Build();

            //string[] graphScopes = { "user.read", "files.read.all", "mail.read", "calendars.read" };

            string[] graphScopes = { "Mail.Read", "Files.Read.All", "Calendars.Read" };

            AuthenticationResult result = null;

            try
            {
                // The AcquireTokenOnBehalfOfAsync method will first look in the MSAL in memory cache for a
                // matching access token. Only if there isn't one, does it initiate the "on behalf of" flow
                // with the Azure AD V2 endpoint.
                result = cca.AcquireTokenOnBehalfOf(graphScopes, userAssertion).ExecuteAsync().Result;
            }
            catch (MsalServiceException e)
            {
                if (e.Message.StartsWith("AADSTS50076"))
                {
                    string responseMessage = String.Format("{{\"AADError\":\"AADSTS50076\",\"Claims\":{0}}}", e.Claims);
                    return(SendErrorToClient(HttpStatusCode.InternalServerError, e, responseMessage));
                }

                if ((e.Message.StartsWith("AADSTS65001")) ||
                    (e.Message.StartsWith("AADSTS70011: The provided value for the input parameter 'scope' is not valid.")))
                {
                    return(SendErrorToClient(HttpStatusCode.InternalServerError, e, e.Message));
                }

                return(SendErrorToClient(HttpStatusCode.InternalServerError, e, e.Message));
            }

            HttpRequestMessage requestMessage = new HttpRequestMessage();
            var configuration = new HttpConfiguration();

            requestMessage.Properties[System.Web.Http.Hosting.HttpPropertyKeys.HttpConfigurationKey] = configuration;
            HttpResponseMessage tokenMessage = requestMessage.CreateResponse(HttpStatusCode.OK, result.AccessToken);

            return(tokenMessage);
        }
        /// <summary>
        /// Authenticate using MS Identity Library
        /// </summary>
        /// <returns></returns>
        private async Task <AuthenticationResult> AuthenticateViaMsal()
        {
            ConfidentialClientApplicationBuilder builder = ConfidentialClientApplicationBuilder.Create(_AzureADConfig.ClientId);

            //builder.WithTenantId(_AzureADConfig.TenantId);
            builder.WithClientSecret(_AzureADConfig.ClientSecret);

            IConfidentialClientApplication app = builder.Build();

            // Acquire Token
            string[] scopes = new string[] { _CustomerApiConfig.Scope };
            return(await app.AcquireTokenForClient(scopes).WithAuthority(CreateOAuthEndPoint(), true).ExecuteAsync());
        }
Example #8
0
        public static IConfidentialClientApplication CreateConfidentialClient(
            string authority             = null,
            string clientId              = null,
            string clientSecret          = null,
            X509Certificate2 certificate = null,
            string redirectUri           = null,
            string tenantId              = null)
        {
            ConfidentialClientApplicationBuilder builder = ConfidentialClientApplicationBuilder.Create(clientId);

            if (!string.IsNullOrEmpty(authority))
            {
                builder = builder.WithAuthority(authority);
            }

            if (!string.IsNullOrEmpty(clientSecret))
            {
                builder = builder.WithClientSecret(clientSecret);
            }

            if (certificate != null)
            {
                builder = builder.WithCertificate(certificate);
            }

            if (!string.IsNullOrEmpty(redirectUri))
            {
                builder = builder.WithRedirectUri(redirectUri);
            }

            if (!string.IsNullOrEmpty(tenantId))
            {
                builder = builder.WithTenantId(tenantId);
            }

            IConfidentialClientApplication client = builder.WithLogging(
                DebugLoggingMethod,
                LogLevel.Info,
                enablePiiLogging: false,
                enableDefaultPlatformLogging: true).Build();

            MsalCacheHelper cacheHelper = InitializeCacheHelper(clientId);

            cacheHelper.RegisterCache(client.UserTokenCache);

            return(client);
        }
        /// <summary>
        /// Creates a confidential client used for generating tokens.
        /// </summary>
        /// <param name="cloudInstance">The cloud instance used for authentication.</param>
        /// <param name="clientId">Identifier of the client requesting the token.</param>
        /// <param name="certificate">Certificate used by the client requesting the token.</param>
        /// <param name="clientSecret">Secret of the client requesting the token.</param>
        /// <param name="redirectUri">The redirect URI for the client.</param>
        /// <param name="tenantId">Identifier of the tenant requesting the token.</param>
        /// <returns>An aptly configured confidential client.</returns>
        private static IConfidentialClientApplication CreateConfidentialClient(
            AzureCloudInstance cloudInstance,
            string clientId              = null,
            string clientSecret          = null,
            X509Certificate2 certificate = null,
            string redirectUri           = null,
            string tenantId              = null)
        {
            ConfidentialClientApplicationBuilder builder = ConfidentialClientApplicationBuilder.Create(clientId);

            builder = builder.WithAuthority(cloudInstance, tenantId);

            if (!string.IsNullOrEmpty(clientSecret))
            {
                builder = builder.WithClientSecret(clientSecret);
            }

            if (certificate != null)
            {
                builder = builder.WithCertificate(certificate);
            }

            if (!string.IsNullOrEmpty(redirectUri))
            {
                builder = builder.WithRedirectUri(redirectUri);
            }

            if (!string.IsNullOrEmpty(tenantId))
            {
                builder = builder.WithTenantId(tenantId);
            }

            IConfidentialClientApplication client = builder.WithLogging((level, message, pii) =>
            {
                MgmtSession.Instance.DebugMessages.Enqueue($"[MSAL] {level} {message}");
            }).Build();

            if (MgmtSession.Instance.TryGetComponent(ComponentKey.TokenCache, out IMgmtTokenCache tokenCache))
            {
                ServiceClientTracing.Information($"[MSAL] Registering the token cache for client {clientId}");
                tokenCache.RegisterCache(client);
            }

            return(client);
        }
        protected override async ValueTask <IConfidentialClientApplication> CreateClientAsync(bool async, CancellationToken cancellationToken)
        {
            ConfidentialClientApplicationBuilder confClientBuilder = ConfidentialClientApplicationBuilder.Create(ClientId).WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, TenantId).WithHttpClientFactory(new HttpPipelineClientFactory(Pipeline.HttpPipeline));

            if (_clientSecret != null)
            {
                confClientBuilder.WithClientSecret(_clientSecret);
            }

            if (_certificateProvider != null)
            {
                X509Certificate2 clientCertificate = await _certificateProvider.GetCertificateAsync(async, cancellationToken).ConfigureAwait(false);

                confClientBuilder.WithCertificate(clientCertificate);
            }

            return(confClientBuilder.Build());
        }
Example #11
0
        /// <summary>
        /// Authorizes the web application (not the user) to access Microsoft Graph resources by using
        /// the Authorization Code flow of OAuth.
        /// </summary>
        /// <returns>The default view.</returns>
        public async Task <ActionResult> Authorize()
        {
            ConfidentialClientApplicationBuilder clientBuilder = ConfidentialClientApplicationBuilder.Create(Settings.AzureADClientId);

            clientBuilder.WithClientSecret(Settings.AzureADClientSecret);
            clientBuilder.WithRedirectUri(loginRedirectUri.ToString());
            clientBuilder.WithAuthority(Settings.AzureADAuthority);
            ConfidentialClientApplication clientApp = (ConfidentialClientApplication)clientBuilder.Build();

            string[] graphScopes = { "Files.Read.All", "User.Read" };


            var authStateString = Request.QueryString["state"];
            var authState       = JsonConvert.DeserializeObject <AuthState>(authStateString);

            try
            {
                // Get and save the token.
                var authResultBuilder = clientApp.AcquireTokenByAuthorizationCode(
                    graphScopes,
                    Request.Params["code"]   // The auth 'code' parameter from the Azure redirect.
                    );

                var authResult = await authResultBuilder.ExecuteAsync();

                await SaveAuthToken(authState, authResult);

                authState.authStatus = "success";
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.ToString());
                authState.authStatus = "failure";
            }

            // Instead of doing a server-side redirect, we have to do a client-side redirect to get around
            // some issues with the display dialog API not getting properly wired up after a server-side redirect
            var redirectUrl = Url.Action(nameof(AuthorizeComplete), new { authState = JsonConvert.SerializeObject(authState) });

            ViewBag.redirectUrl = redirectUrl;
            return(View());
        }
        protected override async ValueTask <IConfidentialClientApplication> CreateClientAsync(bool async, CancellationToken cancellationToken)
        {
            ConfidentialClientApplicationBuilder confClientBuilder = ConfidentialClientApplicationBuilder.Create(ClientId)
                                                                     .WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, TenantId)
                                                                     .WithHttpClientFactory(new HttpPipelineClientFactory(Pipeline.HttpPipeline))
                                                                     .WithLogging(LogMsal, enablePiiLogging: IsPiiLoggingEnabled);

            if (_clientSecret != null)
            {
                confClientBuilder.WithClientSecret(_clientSecret);
            }

            if (_assertionCallback != null)
            {
                confClientBuilder.WithClientAssertion(_assertionCallback);
            }

            if (_asyncAssertionCallback != null)
            {
                confClientBuilder.WithClientAssertion(_asyncAssertionCallback);
            }

            if (_certificateProvider != null)
            {
                X509Certificate2 clientCertificate = await _certificateProvider.GetCertificateAsync(async, cancellationToken).ConfigureAwait(false);

                confClientBuilder.WithCertificate(clientCertificate);
            }

            if (RegionalAuthority.HasValue)
            {
                confClientBuilder.WithAzureRegion(RegionalAuthority.Value.ToString());
            }

            if (!string.IsNullOrEmpty(RedirectUrl))
            {
                confClientBuilder.WithRedirectUri(RedirectUrl);
            }

            return(confClientBuilder.Build());
        }
        /// <summary>
        /// Creates a confidential client used for generating tokens.
        /// </summary>
        /// <param name="cloudInstance">The cloud instance used for authentication.</param>
        /// <param name="clientId">Identifier of the client requesting the token.</param>
        /// <param name="certificate">Certificate used by the client requesting the token.</param>
        /// <param name="clientSecret">Secret of the client requesting the token.</param>
        /// <param name="redirectUri">The redirect URI for the client.</param>
        /// <param name="tenantId">Identifier of the tenant requesting the token.</param>
        /// <returns>An aptly configured confidential client.</returns>
        private static IConfidentialClientApplication CreateConfidentialClient(
            AzureCloudInstance cloudInstance,
            string clientId              = null,
            string clientSecret          = null,
            X509Certificate2 certificate = null,
            string redirectUri           = null,
            string tenantId              = null)
        {
            ConfidentialClientApplicationBuilder builder = ConfidentialClientApplicationBuilder.Create(clientId);

            builder = builder.WithAuthority(cloudInstance, tenantId);

            if (!string.IsNullOrEmpty(clientSecret))
            {
                builder = builder.WithClientSecret(clientSecret);
            }

            if (certificate != null)
            {
                builder = builder.WithCertificate(certificate);
            }

            if (!string.IsNullOrEmpty(redirectUri))
            {
                builder = builder.WithRedirectUri(redirectUri);
            }

            if (!string.IsNullOrEmpty(tenantId))
            {
                builder = builder.WithTenantId(tenantId);
            }

            IConfidentialClientApplication client = builder.WithLogging((level, message, pii) =>
            {
                PartnerSession.Instance.DebugMessages.Enqueue($"[MSAL] {level} {message}");
            }).Build();

            return(client);
        }
        /// <summary>
        /// Executes Authentication against a service
        /// </summary>
        /// <param name="serviceUrl"></param>
        /// <param name="clientCredentials"></param>
        /// <param name="user"></param>
        /// <param name="clientId"></param>
        /// <param name="redirectUri"></param>
        /// <param name="promptBehavior"></param>
        /// <param name="isOnPrem"></param>
        /// <param name="authority"></param>
        /// <param name="userCert">Certificate of provided to login with</param>
        /// <param name="logSink">(optional) Initialized CdsTraceLogger Object</param>
        /// <param name="useDefaultCreds">(optional) if set, tries to login as the current user.</param>
        /// <param name="msalAuthClient">Object of either confidential or public client</param>
        /// <param name="clientSecret"></param>
        /// <param name="addVersionInfoToUri">indicates if the serviceURI should be updated to include the /web?sdk version</param>
        /// <returns>AuthenticationResult containing a JWT Token for the requested Resource and user/app</returns>
        internal async static Task <ExecuteAuthenticationResults> ExecuteAuthenticateServiceProcessAsync(
            Uri serviceUrl,
            ClientCredentials clientCredentials,
            X509Certificate2 userCert,
            string clientId,
            Uri redirectUri,
            PromptBehavior promptBehavior,
            bool isOnPrem,
            string authority,
            object msalAuthClient,
            CdsTraceLogger logSink    = null,
            bool useDefaultCreds      = false,
            SecureString clientSecret = null,
            bool addVersionInfoToUri  = true,
            IAccount user             = null
            )
        {
            ExecuteAuthenticationResults processResult = new ExecuteAuthenticationResults();
            bool createdLogSource = false;

            AuthenticationResult authenticationResult = null;

            try
            {
                if (logSink == null)
                {
                    // when set, the log source is locally created.
                    createdLogSource = true;
                    logSink          = new CdsTraceLogger();
                }

                string Authority = string.Empty;
                string Resource  = string.Empty;

                bool clientCredentialsCheck = clientCredentials != null && clientCredentials.UserName != null && !string.IsNullOrEmpty(clientCredentials.UserName.UserName) && !string.IsNullOrEmpty(clientCredentials.UserName.Password);
                Resource = serviceUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
                if (!Resource.EndsWith("/"))
                {
                    Resource += "/";
                }

                if (addVersionInfoToUri)
                {
                    processResult.TargetServiceUrl = GetUriBuilderWithVersion(serviceUrl).Uri;
                }
                else
                {
                    processResult.TargetServiceUrl = serviceUrl;
                }

                if (!string.IsNullOrWhiteSpace(authority))
                {
                    //Overriding the tenant specific authority if clientCredentials are null
                    Authority = authority;
                }
                else
                {
                    var rslt = GetAuthorityFromTargetServiceAsync(ClientServiceProviders.Instance.GetService <IHttpClientFactory>(), processResult.TargetServiceUrl, logSink).ConfigureAwait(false).GetAwaiter().GetResult();
                    if (!string.IsNullOrEmpty(rslt.Authority))
                    {
                        Authority = rslt.Authority;
                        Resource  = rslt.Resource;
                    }
                    else
                    {
                        throw new ArgumentNullException("Authority", "Need a non-empty authority");
                    }
                }
                //	clientCredentialsCheck = false;  // Forcing system to provide a UX popup vs UID/PW

                // Assign outbound properties.
                processResult.Resource  = Resource;
                processResult.Authority = Authority;

                logSink.Log("AuthenticateService - found authority with name " + (string.IsNullOrEmpty(Authority) ? "<Not Provided>" : Authority));
                logSink.Log("AuthenticateService - found resource with name " + (string.IsNullOrEmpty(Resource) ? "<Not Provided>" : Resource));

                Uri ResourceUri = new Uri(Resource);
                // Add Scope,
                List <string> Scopes = Utilities.AddScope($"{Resource}/user_impersonation");

                AuthenticationResult _authenticationResult = null;
                if (userCert != null || clientSecret != null)
                {
                    // Add Scope,
                    Scopes.Clear();
                    Scopes = Utilities.AddScope($"{Resource}.default", Scopes);

                    IConfidentialClientApplication       cApp        = null;
                    ConfidentialClientApplicationBuilder cAppBuilder = null;

                    if (msalAuthClient is IConfidentialClientApplication)
                    {
                        cApp = (IConfidentialClientApplication)msalAuthClient;
                    }
                    else
                    {
                        cAppBuilder = ConfidentialClientApplicationBuilder.CreateWithApplicationOptions(
                            new ConfidentialClientApplicationOptions()
                        {
                            ClientId         = clientId,
                            EnablePiiLogging = true,
                            LogLevel         = LogLevel.Verbose,
                        })
                                      .WithAuthority(Authority)
                                      .WithLogging(Microsoft.PowerPlatform.Cds.Client.Utils.ADALLoggerCallBack.Log);
                    }

                    if (userCert != null)
                    {
                        logSink.Log("Initial ObtainAccessToken - CERT", TraceEventType.Verbose);
                        cApp = cAppBuilder.WithCertificate(userCert).Build();
                        _authenticationResult = await ObtainAccessTokenAsync(cApp, Scopes, logSink);
                    }
                    else
                    {
                        if (clientSecret != null)
                        {
                            logSink.Log("Initial ObtainAccessToken - Client Secret", TraceEventType.Verbose);
                            cApp = cAppBuilder.WithClientSecret(clientSecret.ToUnsecureString()).Build();
                            _authenticationResult = await ObtainAccessTokenAsync(cApp, Scopes, logSink);
                        }
                        else
                        {
                            throw new Exception("Invalid Cert or Client Secret Auth flow");
                        }
                    }

                    // Update the MSAL Client handed back.
                    processResult.MsalAuthClient = cApp;
                }
                else
                {
                    PublicClientApplicationBuilder cApp = null;
                    IPublicClientApplication       pApp = null;
                    if (msalAuthClient is IPublicClientApplication)
                    {
                        pApp = (IPublicClientApplication)msalAuthClient;
                    }
                    else
                    {
                        cApp = PublicClientApplicationBuilder.CreateWithApplicationOptions(
                            new PublicClientApplicationOptions()
                        {
                            ClientId         = clientId,
                            EnablePiiLogging = true,
                            RedirectUri      = redirectUri.ToString(),
                            LogLevel         = LogLevel.Verbose,
                        })
                               .WithAuthority(Authority)
                               .WithLogging(Microsoft.PowerPlatform.Cds.Client.Utils.ADALLoggerCallBack.Log);

                        pApp = cApp.Build();
                    }

                    //Run user Auth flow.
                    _authenticationResult = await ObtainAccessTokenAsync(pApp, Scopes, user, promptBehavior, clientCredentials, useDefaultCreds, logSink);

                    // Assign the application back out
                    processResult.MsalAuthClient = pApp;

                    //Assigning the authority to ref object to pass back to ConnMgr to store the latest Authority in Credential Manager.
                    authority = Authority;
                }

                if (_authenticationResult != null && _authenticationResult.Account != null)
                {
                    //To use same userId while connecting to OrgService (ConnectAndInitCrmOrgService)
                    //_userId = _authenticationResult.Account;
                    processResult.UserIdent = _authenticationResult.Account;
                }

                if (null == _authenticationResult)
                {
                    throw new ArgumentNullException("AuthenticationResult");
                }
                authenticationResult         = _authenticationResult;
                processResult.MsalAuthResult = authenticationResult;
            }
            catch (AggregateException ex)
            {
                if (ex.InnerException is Microsoft.Identity.Client.MsalException)
                {
                    var errorHandledResult = await ProcessAdalExecptionAsync(serviceUrl, clientCredentials, userCert, clientId, redirectUri, promptBehavior, isOnPrem, authority, msalAuthClient, logSink, useDefaultCreds, (Microsoft.Identity.Client.MsalException) ex.InnerException);

                    if (errorHandledResult != null)
                    {
                        processResult = errorHandledResult;
                    }
                }
                else
                {
                    logSink.Log("ERROR REQUESTING Token FROM THE Authentication context - General ADAL Error", TraceEventType.Error, ex);
                    logSink.Log(ex);
                    throw;
                }
            }
            catch (Microsoft.Identity.Client.MsalException ex)
            {
                var errorHandledResult = await ProcessAdalExecptionAsync(serviceUrl, clientCredentials, userCert, clientId, redirectUri, promptBehavior, isOnPrem, authority, msalAuthClient, logSink, useDefaultCreds, ex);

                if (errorHandledResult != null)
                {
                    processResult = errorHandledResult;
                }
            }
            catch (System.Exception ex)
            {
                logSink.Log("ERROR REQUESTING Token FROM THE Authentication context", TraceEventType.Error);
                logSink.Log(ex);
                throw;
            }
            finally
            {
                if (createdLogSource)                 // Only dispose it if it was created locally.
                {
                    logSink.Dispose();
                }
            }
            return(processResult);
        }
Example #15
0
        public async Task <bool> GetAccessToken(bool throwExceptionIfFail)
        {
            bool      success = true;
            Stopwatch timer   = new Stopwatch();

            timer.Start();
            int timeout = this.Timeout;

            try
            {
                ConfidentialClientApplicationBuilder appBuilder = ConfidentialClientApplicationBuilder.Create(ClientId).WithAuthority(this.CloudInstance, this.Tenant);
                IConfidentialClientApplication       app        = null;
                if (!String.IsNullOrWhiteSpace(ClientSecret))
                {
                    // Get bearer token using a client secret
                    ClaimsProviderLogging.Log($"[{ClaimsProviderName}] Getting new access token for tenant '{Tenant}' on cloud instance '{CloudInstance}' using client ID {ClientId} and a client secret.", TraceSeverity.Verbose, EventSeverity.Information, TraceCategory.Core);
                    app = appBuilder.WithClientSecret(ClientSecret).Build();
                }
                else
                {
                    // Get bearer token using a client certificate
                    ClaimsProviderLogging.Log($"[{ClaimsProviderName}] Getting new access token for tenant '{Tenant}' on cloud instance '{CloudInstance}' using client ID {ClientId} and a client certificate with thumbprint {ClientCertificate.Thumbprint}.", TraceSeverity.Verbose, EventSeverity.Information, TraceCategory.Core);
                    app = appBuilder.WithCertificate(ClientCertificate).Build();
                }
                // Acquire bearer token
                Task <AuthenticationResult> acquireTokenTask = app.AcquireTokenForClient(this.Scopes).ExecuteAsync();
                AuthNResult = await TaskHelper.TimeoutAfter <AuthenticationResult>(acquireTokenTask, new TimeSpan(0, 0, 0, 0, timeout)).ConfigureAwait(false);

                TimeSpan duration = new TimeSpan(AuthNResult.ExpiresOn.UtcTicks - DateTime.Now.ToUniversalTime().Ticks);
                ClaimsProviderLogging.Log($"[{ClaimsProviderName}] Got new access token for tenant '{Tenant}' on cloud instance '{CloudInstance}', valid for {Math.Round((duration.TotalHours), 1)} hour(s) and retrieved in {timer.ElapsedMilliseconds.ToString()} ms", TraceSeverity.High, EventSeverity.Information, TraceCategory.Core);
            }
            catch (MsalServiceException ex)
            {
                ClaimsProviderLogging.Log($"[{ClaimsProviderName}] Unable to get access token for tenant '{Tenant}' on cloud instance '{CloudInstance}': {ex.Message}", TraceSeverity.Unexpected, EventSeverity.Error, TraceCategory.Core);
                success = false;
                if (throwExceptionIfFail)
                {
                    throw;
                }
            }
            catch (TimeoutException)
            {
                ClaimsProviderLogging.Log($"[{ClaimsProviderName}] Could not get access token before timeout of {timeout.ToString()} ms for tenant '{Tenant}' on cloud instance '{CloudInstance}'", TraceSeverity.Unexpected, EventSeverity.Error, TraceCategory.Core);
                success = false;
                if (throwExceptionIfFail)
                {
                    throw;
                }
            }
            catch (Exception ex)
            {
                ClaimsProviderLogging.LogException(ClaimsProviderName, $"while getting access token for tenant '{Tenant}' on cloud instance '{CloudInstance}'", TraceCategory.Lookup, ex);
                success = false;
                if (throwExceptionIfFail)
                {
                    throw;
                }
            }
            finally
            {
                timer.Stop();
            }
            return(success);
        }