public async void SignOut()
        {
            await appBuilder.Build().RemoveAsync(AuthResult.Account);

            _accessToken = null;
            graphClient  = null;
        }
예제 #2
0
        protected virtual ValueTask <IPublicClientApplication> CreateClientCoreAsync(string[] clientCapabilities, bool async, CancellationToken cancellationToken)
        {
            var authorityHost = Pipeline.AuthorityHost;
            var authorityUri  = new UriBuilder(authorityHost.Scheme, authorityHost.Host, authorityHost.Port, TenantId ?? Constants.OrganizationsTenantId).Uri;

            PublicClientApplicationBuilder pubAppBuilder = PublicClientApplicationBuilder
                                                           .Create(ClientId)
                                                           .WithAuthority(authorityUri)
                                                           .WithHttpClientFactory(new HttpPipelineClientFactory(Pipeline.HttpPipeline))
                                                           .WithLogging(LogMsal, enablePiiLogging: IsPiiLoggingEnabled);

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

            if (clientCapabilities.Length > 0)
            {
                pubAppBuilder.WithClientCapabilities(clientCapabilities);
            }

            if (_beforeBuildClient != null)
            {
                _beforeBuildClient(pubAppBuilder);
            }

            return(new ValueTask <IPublicClientApplication>(pubAppBuilder.Build()));
        }
        protected override ValueTask <IPublicClientApplication> CreateClientAsync(bool async, CancellationToken cancellationToken)
        {
            var authorityHost = Pipeline.AuthorityHost;

            var authorityUri = new UriBuilder(authorityHost.Scheme, authorityHost.Host, authorityHost.Port, TenantId ?? Constants.OrganizationsTenantId).Uri;

            PublicClientApplicationBuilder pubAppBuilder = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(authorityUri).WithHttpClientFactory(new HttpPipelineClientFactory(Pipeline.HttpPipeline));

            if (!string.IsNullOrEmpty(_redirectUrl))
            {
                pubAppBuilder = pubAppBuilder.WithRedirectUri(_redirectUrl);
            }

            return(new ValueTask <IPublicClientApplication>(pubAppBuilder.Build()));
        }
예제 #4
0
        static async Task DoIt(bool disableLegacyCache)
        {
            AppCoordinates.AppCoordinates v1App = AppCoordinates.PreRegisteredApps.GetV1App(useInMsal: true);
            string resource = AppCoordinates.PreRegisteredApps.MsGraph;

            string[] scopes = new string[] { resource + "/user.read" };

            string cacheFolder         = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + @"..\..\..\..");
            string adalV3cacheFileName = Path.Combine(cacheFolder, "cacheAdalV3.bin");
            string msalCacheFileName   = Path.Combine(cacheFolder, "cacheMsal.bin");

            AuthenticationResult result;


            PublicClientApplicationBuilder builder = PublicClientApplicationBuilder.Create(v1App.ClientId)
                                                     .WithAuthority(v1App.Authority);

            if (disableLegacyCache)
            {
                Console.WriteLine("Disabled legacy cache.");
                builder.WithLegacyCacheCompatibility(false);
            }

            IPublicClientApplication app = builder.Build();

            FilesBasedTokenCacheHelper.EnableSerialization(app.UserTokenCache,
                                                           msalCacheFileName,
                                                           adalV3cacheFileName);
            var accounts = await app.GetAccountsAsync();

            try
            {
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
                         .ExecuteAsync();

                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine($"Using MSALV4.x got token for '{result.Account.Username}' from the cache");
                Console.ResetColor();
            }
            catch (MsalUiRequiredException ex)
            {
                result = await app.AcquireTokenInteractive(scopes)
                         .ExecuteAsync();

                Console.WriteLine($"Using MSALV4.x got token for '{result.Account.Username}' without the cache");
            }
        }
예제 #5
0
        protected override ValueTask <IPublicClientApplication> CreateClientAsync(bool async, CancellationToken cancellationToken)
        {
            var authorityHost = Pipeline.AuthorityHost;

            var authorityUri = new UriBuilder(authorityHost.Scheme, authorityHost.Host, authorityHost.Port, TenantId ?? Constants.OrganizationsTenantId).Uri;

            PublicClientApplicationBuilder pubAppBuilder = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(authorityUri).WithHttpClientFactory(new HttpPipelineClientFactory(Pipeline.HttpPipeline)).WithLogging(AzureIdentityEventSource.Singleton.LogMsal);

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

            pubAppBuilder.WithClientCapabilities(new string[] { "CP1" });

            return(new ValueTask <IPublicClientApplication>(pubAppBuilder.Build()));
        }
예제 #6
0
        public static IObservable <GraphServiceClient> Authorize(this PublicClientApplicationBuilder builder,
                                                                 Func <ITokenCache, IObservable <TokenCacheNotificationArgs> > storeResults)
        {
            var clientApp   = builder.Build();
            var scopes      = new[] { "user.read", "tasks.readwrite", "calendars.readwrite" };
            var authResults = Observable.FromAsync(() => clientApp.GetAccountsAsync())
                              .Select(accounts => accounts.FirstOrDefault())
                              .SelectMany(account => Observable.FromAsync(() => clientApp.AcquireTokenSilent(scopes, account).ExecuteAsync()))
                              .Catch <AuthenticationResult, MsalUiRequiredException>(e => clientApp.AquireTokenInteractively(scopes, null));
            var authenticationResult = storeResults(clientApp.UserTokenCache)
                                       .Select(args => (AuthenticationResult)null).IgnoreElements()
                                       .Merge(authResults).FirstAsync();

            return(authenticationResult.Select(result => new GraphServiceClient(new DelegateAuthenticationProvider(request => {
                request.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
                request.Headers.Add("Prefer", "IdType=\"ImmutableId\"");
                return System.Threading.Tasks.Task.FromResult(0);
            }))));
        }
        public MsalPublicClient(HttpPipeline pipeline, string clientId, string tenantId = default, string redirectUrl = default, bool attachSharedCache = false)
        {
            PublicClientApplicationBuilder pubAppBuilder = PublicClientApplicationBuilder.Create(clientId).WithHttpClientFactory(new HttpPipelineClientFactory(pipeline));

            tenantId ??= Constants.OrganizationsTenantId;

            pubAppBuilder = pubAppBuilder.WithTenantId(tenantId);

            if (!string.IsNullOrEmpty(redirectUrl))
            {
                pubAppBuilder = pubAppBuilder.WithRedirectUri(redirectUrl);
            }

            _client = pubAppBuilder.Build();

            if (attachSharedCache)
            {
                _cacheReader = new MsalCacheReader(_client.UserTokenCache, Constants.SharedTokenCacheFilePath, Constants.SharedTokenCacheAccessRetryCount, Constants.SharedTokenCacheAccessRetryDelay);
            }
        }
        public MsalPublicClient(HttpPipeline pipeline, Uri authorityHost, string clientId, string tenantId = default, string redirectUrl = default, bool attachSharedCache = false)
        {
            tenantId ??= Constants.OrganizationsTenantId;

            var authorityUri = new UriBuilder(authorityHost.Scheme, authorityHost.Host, authorityHost.Port, tenantId).Uri;

            PublicClientApplicationBuilder pubAppBuilder = PublicClientApplicationBuilder.Create(clientId).WithAuthority(authorityUri).WithHttpClientFactory(new HttpPipelineClientFactory(pipeline));

            pubAppBuilder = pubAppBuilder.WithTenantId(tenantId);

            if (!string.IsNullOrEmpty(redirectUrl))
            {
                pubAppBuilder = pubAppBuilder.WithRedirectUri(redirectUrl);
            }

            _client = pubAppBuilder.Build();

            _clientId = clientId;

            _ensureInitAsync = new Lazy <Task>(InitializeAsync);

            _attachSharedCache = attachSharedCache;
        }
        /// <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);
        }