public async void SignOut() { await appBuilder.Build().RemoveAsync(AuthResult.Account); _accessToken = null; graphClient = null; }
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())); }
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"); } }
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())); }
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); }