private async Task OnBeforeAccessAsync(TokenCacheNotificationArgs args) { _logger.Verbose($"OnBeforeAccessAsync - before getting the lock " + _semaphoreSlim.CurrentCount); // prevent other threads / background tasks from reading the file await _semaphoreSlim.WaitAsync().ConfigureAwait(true); _logger.Verbose($"OnBeforeAccessAsync - acquired the lock"); IStorageFile cacheFile = await ApplicationData.Current.LocalFolder.TryGetItemAsync(CacheFileName) as IStorageFile; if (cacheFile != null) { byte[] decryptedBlob; try { decryptedBlob = await ReadAndDecryptAsync(cacheFile).ConfigureAwait(true); } catch (Exception ex) { _logger.Error("UWP cache file could not be loaded. Using in-memory cache only."); _logger.ErrorPii(ex); return; } if (decryptedBlob != null) { args.TokenCache.DeserializeMsalV3(decryptedBlob); } } }
public static void ValidateIosBrokerRedirectUri(Uri redirectUri, string bundleId, ICoreLogger logger) { string expectedRedirectUri = $"msauth.{bundleId}://auth"; // It's important to use the original string here because the bundleId is case sensitive string actualRedirectUriString = redirectUri.OriginalString; // MSAL style redirect uri - case sensitive if (string.Equals(expectedRedirectUri, actualRedirectUriString.TrimEnd('/'), StringComparison.Ordinal)) { logger.Verbose("Valid MSAL style redirect Uri detected."); return; } // ADAL style redirect uri - my_scheme://{bundleID} if (redirectUri.Authority.Equals(bundleId, StringComparison.OrdinalIgnoreCase)) { logger.Verbose("Valid ADAL style redirect Uri detected."); return; } throw new MsalClientException( MsalError.CannotInvokeBroker, $"The broker redirect URI is incorrect, it should be {expectedRedirectUri} or app_scheme ://{bundleId} - " + $"please visit https://aka.ms/msal-net-xamarin for details about redirect URIs."); }
internal static List <T> FilterWithLogging <T>( this List <T> list, Func <T, bool> predicate, ICoreLogger logger, string logPrefix, bool updateOriginalCollection = true) { if (logger.IsLoggingEnabled(LogLevel.Verbose)) { logger.Verbose($"{logPrefix} - item count before: {list.Count} "); } if (updateOriginalCollection) { list.RemoveAll(e => !predicate(e)); } else { list = list.Where(predicate).ToList(); } if (logger.IsLoggingEnabled(LogLevel.Verbose)) { logger.Verbose($"{logPrefix} - item count after: {list.Count} "); } return(list); }
public bool IsBrokerInstalledAndInvokable() { bool canInvoke = _brokerHelper.CanSwitchToBroker(); _logger.Verbose("Can invoke broker? " + canInvoke); return(canInvoke); }
public bool CanInvokeBroker() { bool canInvoke = _brokerHelper.CanSwitchToBroker(); _logger.Verbose("Can invoke broker? " + canInvoke); return(canInvoke); }
public bool IsBrokerInstalledAndInvokable(AuthorityType authorityType) { using (_logger.LogMethodDuration()) { bool canInvoke = CanSwitchToBroker(); _logger.Verbose("[Android broker] Can invoke broker? " + canInvoke); return(canInvoke); } }
public bool IsBrokerInstalledAndInvokable() { using (_logger.LogMethodDuration()) { bool canInvoke = _brokerHelper.CanSwitchToBroker(); _logger.Verbose("Can invoke broker? " + canInvoke); return(canInvoke); } }
#pragma warning disable VSTHRD100 // Avoid async void methods private async void Authenticator_AccountCommandsRequested( #pragma warning restore VSTHRD100 // Avoid async void methods AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs args) { AccountsSettingsPaneEventDeferral deferral = null; try { deferral = args.GetDeferral(); if (!string.IsNullOrEmpty(_optionalHeaderText)) { args.HeaderText = _optionalHeaderText; } if (string.Equals("common", _authority.TenantId)) { _logger.Verbose("Displaying selector for common"); await AddSelectorsAsync( args, addOrgAccounts : true, addMsaAccounts : true).ConfigureAwait(true); } else if (string.Equals("organizations", _authority.TenantId)) { _logger.Verbose("Displaying selector for organizations"); await AddSelectorsAsync( args, addOrgAccounts : true, addMsaAccounts : _isMsaPassthrough).ConfigureAwait(true); } else if (string.Equals("consumers", _authority.TenantId)) { _logger.Verbose("Displaying selector for consumers"); await AddSelectorsAsync( args, addOrgAccounts : false, addMsaAccounts : true).ConfigureAwait(true); } else { _logger.Verbose("Displaying selector for tenanted authority"); await AddSelectorsAsync( args, addOrgAccounts : true, addMsaAccounts : _isMsaPassthrough, tenantId : _authority.AuthorityInfo.CanonicalAuthority).ConfigureAwait(true); } } finally { deferral?.Complete(); } }
private void WebView2Control_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e) { if (CheckForEndUrl(new Uri(e.Uri))) { _logger.Verbose("[WebView2Control] Redirect uri reached. Stopping the interactive view"); e.Cancel = true; } else { _logger.Verbose("[WebView2Control] Navigating to " + e.Uri); } }
private async Task AcquireTokenInteractiveViaContentProviderAsync(BrokerRequest brokerRequest) { using (_logger.LogMethodDuration()) { _logger.Verbose("[Android broker] Starting interactive authentication. "); Bundle bundleResult = await PerformContentResolverOperationAsync(ContentResolverOperation.acquireTokenInteractive, null).ConfigureAwait(false); var interactiveIntent = CreateInteractiveBrokerIntent(brokerRequest, bundleResult); _brokerHelper.LaunchInteractiveActivity(_parentActivity, interactiveIntent); } }
public InstanceDiscoveryMetadataEntry GetMetadata(string environment, ICoreLogger logger) { s_cache.TryGetValue(environment, out InstanceDiscoveryMetadataEntry entry); logger.Verbose($"[Instance Discovery] Tried to use network cache provider for {environment}. Success? {entry != null}"); return(entry); }
private async Task AcquireTokenInteractiveViaBrokerAsync(BrokerRequest brokerRequest) { using (_logger.LogMethodDuration()) { // onActivityResult will receive the response for this activity. // Launching this activity will switch to the broker app. _logger.Verbose("[Android broker] Starting Android Broker interactive authentication. "); Intent brokerIntent = await GetIntentForInteractiveBrokerRequestAsync(brokerRequest).ConfigureAwait(false); if (brokerIntent != null) { _brokerHelper.LaunchInteractiveActivity(_parentActivity, brokerIntent); } } }
private MsalTokenResponse ProcessBrokerResponse() { using (_logger.LogMethodDuration()) { string[] keyValuePairs = s_brokerResponse.Query.Split('&'); Dictionary <string, string> responseDictionary = new Dictionary <string, string>(StringComparer.InvariantCulture); foreach (string pair in keyValuePairs) { string[] keyValue = pair.Split('='); responseDictionary[keyValue[0]] = CoreHelpers.UrlDecode(keyValue[1]); if (responseDictionary[keyValue[0]].Equals("(null)", StringComparison.OrdinalIgnoreCase) && keyValue[0].Equals(iOSBrokerConstants.Code, StringComparison.OrdinalIgnoreCase)) { responseDictionary[iOSBrokerConstants.Error] = iOSBrokerConstants.BrokerError; _logger.VerbosePii(iOSBrokerConstants.BrokerResponseValuesPii + keyValue.ToString(), iOSBrokerConstants.BrokerResponseContainsError); } } _logger.Verbose(iOSBrokerConstants.ProcessBrokerResponse + responseDictionary.Count); return(ResultFromBrokerResponse(responseDictionary)); } }
public InstanceDiscoveryMetadataEntry GetMetadata( string environment, IEnumerable <string> existingEnvironmentsInCache, ICoreLogger logger) { if (existingEnvironmentsInCache == null) { existingEnvironmentsInCache = Enumerable.Empty <string>(); } bool canUseProvider = existingEnvironmentsInCache.All(e => s_knownEnvironments.ContainsOrdinalIgnoreCase(e)); if (canUseProvider) { s_knownEntries.TryGetValue(environment, out InstanceDiscoveryMetadataEntry entry); logger.Verbose($"[Instance Discovery] Tried to use known metadata provider for {environment}. Success? {entry != null}"); return(entry); } logger.VerbosePii( $"[Instance Discovery] Could not use known metadata provider because at least one environment in the cache is not known. Environments in cache: {string.Join(" ", existingEnvironmentsInCache)} ", $"[Instance Discovery] Could not use known metadata provider because at least one environment in the cache is not known"); return(null); }
public AndroidBrokerHelper(Context androidContext, ICoreLogger logger) { _androidContext = androidContext ?? throw new ArgumentNullException(nameof(androidContext)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _logger.Verbose("Getting the Android context for broker request"); _androidAccountManager = AccountManager.Get(_androidContext); }
public async Task <Uri> ListenToSingleRequestAndRespondAsync( int port, Func <Uri, MessageAndHttpCode> responseProducer, CancellationToken cancellationToken) { TestBeforeTopLevelCall?.Invoke(); cancellationToken.ThrowIfCancellationRequested(); HttpListener httpListener = null; try { string urlToListenTo = "http://localhost:" + port + "/"; httpListener = new HttpListener(); httpListener.Prefixes.Add(urlToListenTo); TestBeforeStart?.Invoke(); httpListener.Start(); _logger.Info("Listening for authorization code on " + urlToListenTo); using (cancellationToken.Register(() => { _logger.Warning("HttpListener stopped because cancellation was requested."); TryStopListening(httpListener); })) { TestBeforeGetContext?.Invoke(); HttpListenerContext context = await httpListener.GetContextAsync() .ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); Respond(responseProducer, context); _logger.Verbose("HttpListner received a message on " + urlToListenTo); // the request URL should now contain the auth code and pkce return(context.Request.Url); } } // If cancellation is requested before GetContextAsync is called, then either // an ObjectDisposedException or an HttpListenerException is thrown. // But this is just cancellation... catch (Exception ex) when(ex is HttpListenerException || ex is ObjectDisposedException) { _logger.Info("HttpListenerException - cancellation requested? " + cancellationToken.IsCancellationRequested); cancellationToken.ThrowIfCancellationRequested(); // if cancellation was not requested, propagate original ex throw; } finally { TryStopListening(httpListener); } }
public async Task <MsalTokenResponse> AcquireTokenInteractiveAsync( AuthenticationRequestParameters authenticationRequestParameters, AcquireTokenInteractiveParameters acquireTokenInteractiveParameters) { MsalTokenResponse msalTokenResponse = null; //need to provide a handle if (_parentHandle == IntPtr.Zero) { throw new MsalClientException( "window_handle_required", "Public Client applications wanting to use WAM need to provide their window handle. Console applications can use GetConsoleWindow Windows API for this."); } //if OperatingSystemAccount is passed then we use the user signed-in on the machine if (PublicClientApplication.IsOperatingSystemAccount(authenticationRequestParameters.Account)) { return(await AcquireTokenInteractiveDefaultUserAsync(authenticationRequestParameters, acquireTokenInteractiveParameters).ConfigureAwait(false)); } var cancellationToken = authenticationRequestParameters.RequestContext.UserCancellationToken; _logger.Verbose("[WamBroker] Using Windows account picker."); using (var core = new NativeInterop.Core()) using (var authParams = WamAdapters.GetCommonAuthParameters(authenticationRequestParameters, _wamOptions.MsaPassthrough)) { //Login Hint string loginHint = authenticationRequestParameters.LoginHint ?? authenticationRequestParameters?.Account?.Username; _logger.Verbose("[WamBroker] AcquireTokenInteractive - login hint provided? " + string.IsNullOrEmpty(loginHint)); using (var result = await core.SignInInteractivelyAsync( _parentHandle, authParams, authenticationRequestParameters.CorrelationId.ToString("D"), loginHint, cancellationToken).ConfigureAwait(false)) { if (result.IsSuccess) { msalTokenResponse = WamAdapters.ParseRuntimeResponse(result, authenticationRequestParameters, _logger); _logger.Verbose("[WamBroker] Successfully retrieved token."); } else { _logger.Error($"[WamBroker] Could not login interactively. {result.Error}"); WamAdapters.ThrowExceptionFromWamError(result, authenticationRequestParameters, _logger); } } } return(msalTokenResponse); }
protected override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { await UpdateRequestWithAccountAsync().ConfigureAwait(false); bool isBrokerConfigured = AuthenticationRequestParameters.IsBrokerConfigured && ServiceBundle.PlatformProxy.CanBrokerSupportSilentAuth(); try { if (AuthenticationRequestParameters.Account != null) { _logger.Verbose("Attempting to acquire token using using local cache..."); return(await _clientStrategy.ExecuteAsync(cancellationToken).ConfigureAwait(false)); } if (!isBrokerConfigured) { _logger.Verbose("No account passed to AcquireTokenSilent"); throw new MsalUiRequiredException( MsalError.UserNullError, MsalErrorMessage.MsalUiRequiredMessage, null, UiRequiredExceptionClassification.AcquireTokenSilentFailed); } _logger.Verbose("No account passed to AcquireTokenSilent. Only the Windows broker (WAM) may be able to log in user with a default account..."); return(await _brokerStrategyLazy.Value.ExecuteAsync(cancellationToken).ConfigureAwait(false)); } catch (MsalException ex) { _logger.Verbose("Token cache could not satisfy silent request"); if (isBrokerConfigured && ShouldTryWithBrokerError(ex.ErrorCode)) { _logger.Info("Attempting to use broker instead"); return(await _brokerStrategyLazy.Value.ExecuteAsync(cancellationToken).ConfigureAwait(false)); } throw; } }
internal static IEnumerable <T> FilterWithLogging <T>( this IEnumerable <T> list, Func <T, bool> predicate, ICoreLogger logger, string logPrefix) { if (logger.IsLoggingEnabled(LogLevel.Verbose)) { logger.Verbose($"{logPrefix} - item count before: {list.Count()} "); } list = list.Where(predicate); if (logger.IsLoggingEnabled(LogLevel.Verbose)) { logger.Verbose($"{logPrefix} - item count after: {list.Count()} "); } return(list); }
public async Task <string> TryFetchTransferTokenAsync(AuthenticationRequestParameters authenticationRequestParameters, WebAccountProvider accountProvider) { // Apps can have MSA-PT enabled and can configured to allow MSA users // However, some older apps have 2 incarnations, one in AAD tenant and one in MSA tenant // For this second case, we can't fetch the transfer token from the client_ID in AAD and this will fail _logger.Verbose("WAM MSA-PT - fetching transfer token"); string transferToken = await FetchMsaPassthroughTransferTokenAsync( authenticationRequestParameters, accountProvider) .ConfigureAwait(false); return(transferToken); }
private void CleanCache(ICoreLogger logger) { if (_lastCleanupTime + s_cleanupCacheInterval < DateTimeOffset.UtcNow && !_cleanupInProgress) { lock (_padlock) { if (!_cleanupInProgress) { logger.Verbose($"[Throttling] Cache size before cleaning up {_cache.Count}"); _cleanupInProgress = true; CleanupCacheNoLocks(); _lastCleanupTime = DateTimeOffset.UtcNow; _cleanupInProgress = false; logger.Verbose($"[Throttling] Cache size after cleaning up {_cache.Count}"); } } } }
public async Task <InstanceDiscoveryMetadataEntry> GetMetadataAsync(Uri authority, RequestContext requestContext) { ICoreLogger logger = requestContext.Logger; string environment = authority.Host; InstanceDiscoveryMetadataEntry cachedEntry = _networkCacheMetadataProvider.GetMetadata(environment, logger); if (cachedEntry == null) { Uri regionalizedAuthority = await BuildAuthorityWithRegionAsync(authority, requestContext).ConfigureAwait(false); CacheInstanceDiscoveryMetadata(CreateEntry(authority, regionalizedAuthority)); cachedEntry = _networkCacheMetadataProvider.GetMetadata(environment, logger); logger.Verbose($"[Region Discovery] Created metadata for the regional environment {environment} ? {cachedEntry != null}"); } else { logger.Verbose($"[Region Discovery] The network provider found an entry for {environment}"); LogTelemetryData(cachedEntry.PreferredNetwork.Split('.')[0], RegionSource.Cache, requestContext); } return(cachedEntry); }
public async Task <string> FetchTransferTokenAsync(AuthenticationRequestParameters authenticationRequestParameters, WebAccountProvider accountProvider) { if (!authenticationRequestParameters.AppConfig.IsMsaPassthrough) { throw new InvalidOperationException("Not configured for msa-pt"); } _logger.Verbose("WAM MSA-PT - fetching transfer token"); string transferToken = await FetchMsaPassthroughTransferTokenAsync( authenticationRequestParameters, accountProvider) .ConfigureAwait(false); return(transferToken); }
public AccountPicker( IntPtr parentHandle, ICoreLogger logger, SynchronizationContext synchronizationContext, Authority authority, bool isMsaPassthrough) { _parentHandle = parentHandle; _logger = logger; _synchronizationContext = synchronizationContext; _authority = authority; _isMsaPassthrough = isMsaPassthrough; _logger.Verbose("Is MSA passthrough? " + _isMsaPassthrough); }
private void ValidateRedirectUri(Uri redirectUri) { string bundleId = NSBundle.MainBundle.BundleIdentifier; string expectedRedirectUri = $"msauth.{bundleId}://auth"; // MSAL style redirect uri - case sensitive if (string.Equals(expectedRedirectUri, redirectUri.AbsoluteUri, StringComparison.Ordinal)) { _logger.Verbose("Valid MSAL style redirect Uri detected."); return; } // ADAL style redirect uri - my_scheme://{bundleID} if (redirectUri.Authority.Equals(bundleId, StringComparison.Ordinal)) { _logger.Verbose("Valid ADAL style redirect Uri detected."); return; } throw new MsalClientException( MsalError.CannotInvokeBroker, $"The broker redirect URI is incorrect, it should be {expectedRedirectUri} or app_scheme ://{bundleId} - " + $"please visit https://aka.ms/msal-net-xamarin for details about redirect URIs."); }
public InstanceDiscoveryMetadataEntry GetMetadataOrThrow(string environment, ICoreLogger logger) { _entries.TryGetValue(environment ?? "", out InstanceDiscoveryMetadataEntry entry); logger.Verbose($"[Instance Discovery] Tried to use user metadata provider for {environment}. Success? {entry != null}"); if (entry == null) { throw new MsalClientException( MsalError.InvalidUserInstanceMetadata, MsalErrorMessage.NoUserInstanceMetadataEntry(environment)); } return(entry); }
public async Task <string> TryFetchTransferTokenInteractiveAsync(AuthenticationRequestParameters authenticationRequestParameters, WebAccountProvider accountProvider) { // First party apps can have MSA-PT enabled and can configured to allow MSA users _logger.Verbose("WAM MSA-PT - fetching transfer token for interactive flow"); var webTokenRequestMsa = await _msaPlugin.CreateWebTokenRequestAsync( accountProvider, authenticationRequestParameters, isForceLoginPrompt : false, isInteractive : true, isAccountInWam : false, TransferTokenScopes) .ConfigureAwait(false); WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequestMsa, _logger); var transferResponse = await _wamProxy.RequestTokenForWindowAsync(_parentHandle, webTokenRequestMsa) .ConfigureAwait(true); return(ExtractTransferToken( authenticationRequestParameters.AppConfig.ClientId, transferResponse, isInteractive: true)); }
private bool VerifyAuthenticator() { using (_logger.LogMethodDuration()) { foreach (AuthenticatorDescription authenticator in Authenticators) { if (authenticator.Type.Equals(BrokerConstants.BrokerAccountType, StringComparison.OrdinalIgnoreCase) && VerifySignature(authenticator.PackageName)) { _logger.Verbose("Found the Authenticator on the device. "); return(true); } } _logger.Warning("No Authenticator found on the device. "); return(false); } }
private bool VerifyAuthenticator() { // there may be multiple authenticators from same package // , but there is only one entry for an authenticator type in // AccountManager. // If another app tries to install same authenticator type, it will // queue up and will be active after first one is uninstalled. AuthenticatorDescription[] authenticators = _androidAccountManager.GetAuthenticatorTypes(); foreach (AuthenticatorDescription authenticator in authenticators) { if (authenticator.Type.Equals(BrokerConstants.BrokerAccountType, StringComparison.OrdinalIgnoreCase) && VerifySignature(authenticator.PackageName)) { _logger.Verbose("Found the Authenticator on the device"); return(true); } } _logger.Warning("No Authenticator found on the device."); return(false); }
private async void Authenticator_AccountCommandsRequested( AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs e) { AccountsSettingsPaneEventDeferral deferral = null; try { deferral = e.GetDeferral(); if (string.Equals("common", _authority.TenantId)) { _logger.Verbose("Displaying selector for common"); e.WebAccountProviderCommands.Add( new WebAccountProviderCommand( await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", "consumers"), WebAccountProviderCommandInvoked)); e.WebAccountProviderCommands.Add( new WebAccountProviderCommand( await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", "organizations"), WebAccountProviderCommandInvoked)); } else if (string.Equals("organizations", _authority.TenantId)) { _logger.Verbose("Displaying selector for organizations"); e.WebAccountProviderCommands.Add( new WebAccountProviderCommand( await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", "organizations"), WebAccountProviderCommandInvoked)); } else if (string.Equals("consumers", _authority.TenantId)) { _logger.Verbose("Displaying selector for consumers"); e.WebAccountProviderCommands.Add( new WebAccountProviderCommand( await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", "consumers"), WebAccountProviderCommandInvoked)); if (_isMsaPassthrough) { e.WebAccountProviderCommands.Add( new WebAccountProviderCommand( await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", "organizations"), WebAccountProviderCommandInvoked)); } } else { _logger.Verbose("Displaying selector for tenanted authority"); e.WebAccountProviderCommands.Add( new WebAccountProviderCommand( await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", _authority.AuthorityInfo.CanonicalAuthority), WebAccountProviderCommandInvoked)); } //e.HeaderText = "Please select an account to log in with"; // TODO: this is English only, try removing it } finally { deferral?.Complete(); } }