public async Task ATS_Expired_NeedsRefresh_AADInvalidResponse_Async() { // Arrange using (MockHttpAndServiceBundle harness = base.CreateTestHarness()) { Trace.WriteLine("1. Setup an app with a token cache with one AT"); PublicClientApplication app = SetupPca(harness); Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed, but is also expired"); UpdateATWithRefreshOn(app.UserTokenCacheInternal.Accessor, DateTime.UtcNow - TimeSpan.FromMinutes(1), true); TokenCacheAccessRecorder cacheAccess = app.UserTokenCache.RecordAccess(); Trace.WriteLine("3. Configure AAD to be unavaiable"); harness.HttpManager.AddAllMocks(TokenResponseType.Invalid_AADUnavailable503); harness.HttpManager.AddTokenResponse(TokenResponseType.Invalid_AADUnavailable503); var account = new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null); // Act MsalServiceException ex = await AssertException.TaskThrowsAsync <MsalServiceException>(() => app .AcquireTokenSilent( TestConstants.s_scope.ToArray(), account) .ExecuteAsync()) .ConfigureAwait(false); Assert.IsFalse(ex is MsalUiRequiredException, "5xx exceptions do not translate to MsalUIRequired"); Assert.AreEqual(503, ex.StatusCode); } }
public async Task MexParsingFailsTestAsync() { using (var httpManager = new MockHttpManager()) { httpManager.AddInstanceDiscoveryMockHandler(); httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityCommonTenant); AddMockHandlerDefaultUserRealmDiscovery(httpManager); // MEX httpManager.AddMockHandlerContentNotFound(HttpMethod.Get, "https://msft.sts.microsoft.com/adfs/services/trust/mex"); PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); // Call acquire token MsalServiceException result = await AssertException.TaskThrowsAsync <MsalServiceException>( async() => await app.AcquireTokenByUsernamePassword( TestConstants.s_scope, TestConstants.s_user.Username, _secureString).ExecuteAsync(CancellationToken.None).ConfigureAwait(false)).ConfigureAwait(false); // Check inner exception Assert.AreEqual("Response status code does not indicate success: 404 (NotFound).", result.Message); // There should be no cached entries. Assert.AreEqual(0, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); } }
public static void CreateErrorResponse(HttpResponse response, RequestContext requestContext) { MsalServiceException serviceEx; try { TokenResponse tokenResponse = JsonHelper.DeserializeFromJson <TokenResponse>(response.Body); if (MsalUiRequiredException.InvalidGrantError.Equals(tokenResponse.Error, StringComparison.OrdinalIgnoreCase)) { throw new MsalUiRequiredException(MsalUiRequiredException.InvalidGrantError, tokenResponse.ErrorDescription) { Claims = tokenResponse.Claims }; } serviceEx = new MsalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription, (int)response.StatusCode, tokenResponse.Claims, null) { ResponseBody = response.Body }; } catch (SerializationException) { serviceEx = new MsalServiceException(MsalException.UnknownError, response.Body, (int)response.StatusCode); } requestContext.Logger.Error(serviceEx); requestContext.Logger.ErrorPii(serviceEx); throw serviceEx; }
public async Task ClientCreds_Expired_NeedsRefresh_AADInvalidResponse_Async() { // Arrange using (MockHttpAndServiceBundle harness = base.CreateTestHarness()) { Trace.WriteLine("1. Setup an app with a token cache with one AT"); ConfidentialClientApplication app = SetupCca(harness); Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed, but is also expired"); UpdateATWithRefreshOn(app.AppTokenCacheInternal.Accessor, DateTime.UtcNow - TimeSpan.FromMinutes(1), true); TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess(); Trace.WriteLine("3. Configure AAD to be unavaiable"); AddHttpMocks(TokenResponseType.Invalid_AADUnavailable, harness.HttpManager, pca: false); // Act MsalServiceException ex = await AssertException.TaskThrowsAsync <MsalServiceException>(() => app .AcquireTokenForClient(TestConstants.s_scope) .ExecuteAsync()) .ConfigureAwait(false); Assert.IsFalse(ex is MsalUiRequiredException, "5xx exceptions do not translate to MsalUIRequired"); Assert.AreEqual(504, ex.StatusCode); cacheAccess.AssertAccessCounts(1, 0); } }
public async Task ValidateAuthorityFalse_SkipsNetworkCall_Async() { // Arrange var validationException = new MsalServiceException(MsalError.InvalidInstance, "authority validation failed"); // Inject authority in service bundle var httpManager = new MockHttpManager(); var appConfig = new ApplicationConfiguration() { HttpManager = httpManager, AuthorityInfo = AuthorityInfo.FromAuthorityUri(Authority, false) }; var serviceBundle = ServiceBundle.Create(appConfig); RequestContext requestContext = new RequestContext(serviceBundle, Guid.NewGuid()); // network fails with invalid_instance exception _networkMetadataProvider .When(x => x.GetMetadataAsync(Arg.Any <Uri>(), requestContext)) .Do(x => throw validationException); InstanceDiscoveryMetadataEntry actualResult = await _discoveryManager.GetMetadataEntryAsync( AuthorityInfo.FromAuthorityUri("https://some_env.com/tid", true), requestContext).ConfigureAwait(false); // Since the validateAuthority is set to false, proceed without alias. ValidateSingleEntryMetadata(new Uri(Authority), actualResult); }
public void MsalServiceException_FromHttpResponse() { // Arrange string responseBody = jsonError; var statusCode = HttpStatusCode.BadRequest; var retryAfterSpan = new TimeSpan(3600); var httpResponse = new HttpResponseMessage(statusCode) { Content = new StringContent(responseBody) }; httpResponse.Headers.RetryAfter = new RetryConditionHeaderValue(retryAfterSpan); HttpResponse msalhttpResponse = HttpManager.CreateResponseAsync(httpResponse).Result; // Act var msalException = new MsalServiceException(ExCode, ExMessage) { HttpResponse = msalhttpResponse }; // Assert var msalServiceException = msalException as MsalServiceException; Assert.AreEqual(ExCode, msalServiceException.ErrorCode); Assert.AreEqual(responseBody, msalServiceException.ResponseBody); Assert.AreEqual(ExMessage, msalServiceException.Message); Assert.AreEqual((int)statusCode, msalServiceException.StatusCode); Assert.AreEqual("some_suberror", msalServiceException.SubError); Assert.AreEqual(retryAfterSpan, msalServiceException.Headers.RetryAfter.Delta); }
public void MsalServiceException_Oauth2Response_Only() { // Arrange HttpResponse httpResponse = new HttpResponse() { Body = jsonError, StatusCode = HttpStatusCode.BadRequest, // 400 }; OAuth2ResponseBase oAuth2Response = JsonHelper.TryToDeserializeFromJson <OAuth2ResponseBase>(httpResponse?.Body); // Act var msalException = new MsalServiceException(ExCode, ExMessage) { OAuth2Response = oAuth2Response }; // Assert var msalServiceException = msalException as MsalServiceException; Assert.AreEqual(ExCode, msalServiceException.ErrorCode); Assert.AreEqual(ExMessage, msalServiceException.Message); Assert.AreEqual("some_claims", msalServiceException.Claims); Assert.AreEqual("6347d33d-941a-4c35-9912-a9cf54fb1b3e", msalServiceException.CorrelationId); Assert.AreEqual("some_suberror", msalServiceException.SubError); }
/// <summary> /// Method for handling exceptions thrown by the MSAL library. /// </summary> /// <param name="mse">Intance of an excpetion of the type <see cref="MsalServiceException"/>> </param> /// <returns></returns> private static void ProcessMsalException(MsalServiceException mse) { switch (mse.ErrorCode) { case MsalServiceException.InvalidAuthority: // What happens: When the library attempts to discover the authority and get the endpoints it // needs to acquire a token, it got an un-authorize HTTP code or an unexpected response // Remediation: // Check that the authority configured for the application, or passed on some overrides // of token acquisition tokens supporting authority override is correct case "unauthorized_client": // For instance: AADSTS700016: Application with identifier '{clientId}' was not found in the directory '{domain}'. // This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. // You may have sent your authentication request to the wrong tenant // Cause: The clientId in the app.config is wrong // Remediation: check the clientId and the app registration Console.WriteLine("The application is not configured correctly with Azure AD"); break; case MsalServiceException.RequestTimeout: case MsalServiceException.ServiceNotAvailable: Console.WriteLine("Acquiring a security token to call Graph failed. Please try later"); break; default: Console.WriteLine(mse.Message); Console.WriteLine("Error occured with Graph call"); break; } }
public async Task FailedAuthorityValidationTestAsync() { LabResponse labResponse = await LabUserHelper.GetDefaultUserAsync().ConfigureAwait(false); LabUser user = labResponse.User; IPublicClientApplication pca = PublicClientApplicationBuilder .Create(labResponse.App.AppId) .WithAuthority("https://bogus.microsoft.com/common") .WithTestLogging() .Build(); Trace.WriteLine("Acquire a token using a not so common authority alias"); MsalServiceException exception = await AssertException.TaskThrowsAsync <MsalServiceException>(() => pca.AcquireTokenByUsernamePassword( s_scopes, user.Upn, new NetworkCredential("", user.GetOrFetchPassword()).SecurePassword) .ExecuteAsync()) .ConfigureAwait(false); Assert.IsTrue(exception.Message.Contains("AADSTS50049")); Assert.AreEqual("invalid_instance", exception.ErrorCode); }
internal async Task <AuthenticationResult> HandleTokenRefreshErrorAsync(MsalServiceException e, MsalAccessTokenCacheItem cachedAccessTokenItem) { var logger = AuthenticationRequestParameters.RequestContext.Logger; bool isAadUnavailable = e.IsAadUnavailable(); logger.Warning($"Fetching a new AT failed. Is AAD down? {isAadUnavailable}. Is there an AT in the cache that is usable? {cachedAccessTokenItem != null}"); if (cachedAccessTokenItem != null && isAadUnavailable) { logger.Info("Returning existing access token. It is not expired, but should be refreshed. "); var idToken = await CacheManager.GetIdTokenCacheItemAsync(cachedAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); var tenantProfiles = await CacheManager.GetTenantProfilesAsync(cachedAccessTokenItem.HomeAccountId).ConfigureAwait(false); return(new AuthenticationResult( cachedAccessTokenItem, idToken, tenantProfiles?.Values, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache, AuthenticationRequestParameters.RequestContext.ApiEvent)); } logger.Warning("Either the exception does not indicate a problem with AAD or the token cache does not have an AT that is usable. "); throw e; }
public async Task MexParsingFailsTestAsync() { using (var httpManager = new MockHttpManager()) { httpManager.AddInstanceDiscoveryMockHandler(); AddMockHandlerDefaultUserRealmDiscovery(httpManager); // MEX httpManager.AddMockHandlerContentNotFound(HttpMethod.Get, "https://msft.sts.microsoft.com/adfs/services/trust/mex"); PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .BuildConcrete(); // Call acquire token MsalServiceException result = await AssertException.TaskThrowsAsync <MsalServiceException>( async() => await app.AcquireTokenByUsernamePassword( TestConstants.s_scope, TestConstants.s_user.Username, _secureString).ExecuteAsync(CancellationToken.None).ConfigureAwait(false)).ConfigureAwait(false); // Check inner exception string expectedError = string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.HttpRequestUnsuccessful + "See https://aka.ms/msal-net-ropc for more information. ", "404", "NotFound"); Assert.AreEqual(expectedError, result.Message); // There should be no cached entries. Assert.AreEqual(0, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); } }
public void ScrubPiiExceptionsTest() { Exception ex = new Exception("test message"); var result = ex.GetPiiScrubbedDetails(); Assert.AreEqual("Exception type: System.Exception", result); result = ((Exception)null).GetPiiScrubbedDetails(); Assert.AreEqual(null, result); Exception innerException = new Exception("test message", new Exception("inner message")); result = innerException.GetPiiScrubbedDetails(); Assert.AreEqual("Exception type: System.Exception---> Exception type: System.Exception\r\n=== End of inner exception stack trace ===", result); MsalException msalException = new MsalException("Msal Exception"); result = msalException.GetPiiScrubbedDetails(); Assert.AreEqual("Exception type: Microsoft.Identity.Client.MsalException, ErrorCode: Msal Exception", result); MsalServiceException msalServiceException = new MsalServiceException("ErrorCode", "Msal Service Exception"); result = msalServiceException.GetPiiScrubbedDetails(); Assert.AreEqual("Exception type: Microsoft.Identity.Client.MsalServiceException, ErrorCode: ErrorCode, StatusCode: 0", result); }
public async Task ClientCreds_Expired_NeedsRefresh_AADInvalidResponse_Async() { // Arrange using (MockHttpAndServiceBundle harness = base.CreateTestHarness()) { Trace.WriteLine("1. Setup an app with a token cache with one AT = expired and needs refersh"); ConfidentialClientApplication app = SetupCca(harness); var atItem = TokenCacheHelper.CreateAccessTokenItem(); UpdateATWithRefreshOn(atItem, DateTime.UtcNow - TimeSpan.FromMinutes(1), true); TokenCacheHelper.PopulateDefaultAppTokenCache(app, atItem); TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess(); Trace.WriteLine("2. Configure AAD to be unavaiable"); harness.HttpManager.AddAllMocks(TokenResponseType.Invalid_AADUnavailable503); harness.HttpManager.AddTokenResponse(TokenResponseType.Invalid_AADUnavailable503); // Act MsalServiceException ex = await AssertException.TaskThrowsAsync <MsalServiceException>(() => app .AcquireTokenForClient(TestConstants.s_scope) .ExecuteAsync()) .ConfigureAwait(false); Assert.IsFalse(ex is MsalUiRequiredException, "5xx exceptions do not translate to MsalUIRequired"); Assert.AreEqual(503, ex.StatusCode); cacheAccess.AssertAccessCounts(1, 0); } }
public void ExceptionsArePubliclyCreatable_ServiceException() { var ex = new MsalServiceException("code1", "msg1"); Assert.AreEqual("code1", ex.ErrorCode); Assert.AreEqual("msg1", ex.Message); Assert.IsNull(ex.InnerException); }
public ThrottlingCacheEntry( MsalServiceException exception, TimeSpan lifetime) { Exception = exception ?? throw new ArgumentNullException(nameof(exception)); CreationTime = DateTimeOffset.UtcNow; ExpirationTime = CreationTime.Add(lifetime); }
public async Task <T> GetResponseAsync <T>(string endpointType) { T typedResponse = default(T); ClientMetrics clientMetrics = new ClientMetrics(); try { clientMetrics.BeginClientMetricsRecord(this.CallState); Dictionary <string, string> clientMetricsHeaders = clientMetrics.GetPreviousRequestRecord(this.CallState); foreach (KeyValuePair <string, string> kvp in clientMetricsHeaders) { this.Client.Headers[kvp.Key] = kvp.Value; } IDictionary <string, string> adalIdHeaders = MsalIdHelper.GetMsalIdParameters(); foreach (KeyValuePair <string, string> kvp in adalIdHeaders) { this.Client.Headers[kvp.Key] = kvp.Value; } IHttpWebResponse response; using (response = await this.Client.GetResponseAsync().ConfigureAwait(false)) { typedResponse = DeserializeResponse <T>(response.ResponseStream); clientMetrics.SetLastError(null); } } catch (HttpRequestWrapperException ex) { PlatformPlugin.Logger.Error(this.CallState, ex); MsalServiceException serviceEx; if (ex.WebResponse != null) { TokenResponse tokenResponse = TokenResponse.CreateFromErrorResponse(ex.WebResponse); string[] errorCodes = tokenResponse.ErrorCodes ?? new[] { ex.WebResponse.StatusCode.ToString() }; serviceEx = new MsalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription, errorCodes, ex); } else { serviceEx = new MsalServiceException(MsalError.Unknown, ex); } clientMetrics.SetLastError(serviceEx.ServiceErrorCodes); PlatformPlugin.Logger.Error(CallState, serviceEx); throw serviceEx; } finally { clientMetrics.EndClientMetricsRecord(endpointType, this.CallState); } return(typedResponse); }
/// <summary> /// Logs the execption event. /// </summary> private void LogExceptionEvent() { if (qosEvent == null) { return; } ExceptionTelemetry exceptionTelemetry = new ExceptionTelemetry(qosEvent.Exception) { Message = "The message has been removed due to PII" }; if (qosEvent.Exception is MsalServiceException) { MsalServiceException ex = qosEvent.Exception as MsalServiceException; exceptionTelemetry.Properties.Add("CorrelationId", ex.CorrelationId); exceptionTelemetry.Properties.Add("ErrorCode", ex.ErrorCode); exceptionTelemetry.Properties.Add("StatusCode", ex.StatusCode.ToString(CultureInfo.InvariantCulture)); } if (qosEvent.Exception is PartnerException) { PartnerException ex = qosEvent.Exception as PartnerException; exceptionTelemetry.Properties.Add("ErrorCategory", ex.ErrorCategory.ToString()); PopulatePropertiesFromResponse(exceptionTelemetry.Properties, ex.Response); if (ex.ServiceErrorPayload != null) { exceptionTelemetry.Properties.Add("ErrorCode", ex.ServiceErrorPayload.ErrorCode); } } else if (qosEvent.Exception is RestException) { object ex = qosEvent.Exception as object; HttpResponseMessageWrapper response = ex.GetType().GetProperty("Response").GetValue(ex, null) as HttpResponseMessageWrapper; PopulatePropertiesFromResponse(exceptionTelemetry.Properties, response); } exceptionTelemetry.Metrics.Add("Duration", qosEvent.Duration.TotalMilliseconds); PopulatePropertiesFromQos(exceptionTelemetry.Properties); try { telemetryClient.TrackException(exceptionTelemetry); } catch { // Ignore any error with capturing the telemetry } }
public void GetRetryAfter_ShouldThrowExceptionWhenRetryAfterHeaderIsNotSet() { string errorCode = "foo_error"; IPublicClientApplication pca = DeviceCodeProvider.CreateClientApplication("clientId"); DeviceCodeProvider authProvider = new DeviceCodeProvider(pca, new string[] { "foo.bar" }); MsalServiceException msalServiceException = new MsalServiceException(errorCode, "bar_foo_error"); MsalServiceException exception = Assert.ThrowsException <MsalServiceException>(() => authProvider.GetRetryAfter(msalServiceException)); Assert.AreEqual(errorCode, exception.ErrorCode); Assert.AreEqual(ErrorConstants.Message.MissingRetryAfterHeader, exception.Message); }
public void MsalServiceExceptionCanSerializeAndDeserializeRoundTrip() { var ex = new MsalServiceException(SomeErrorCode, SomeErrorMessage) { Claims = SomeClaims, CorrelationId = SomeCorrelationId, ResponseBody = SomeResponseBody, SubError = SomeSubError }; SerializeDeserializeAndValidate(ex, typeof(MsalServiceException), true); }
public static void CreateErrorResponse(HttpResponse response, RequestContext requestContext) { bool shouldLogAsError = true; var httpErrorCodeMessage = string.Format(CultureInfo.InvariantCulture, "HttpStatusCode: {0}: {1}", (int)response.StatusCode, response.StatusCode.ToString()); requestContext.Logger.Info(httpErrorCodeMessage); Exception exceptionToThrow = null; try { exceptionToThrow = ExtractErrorsFromTheResponse(response, ref shouldLogAsError); } catch (SerializationException) // in the rare case we get an error response we cannot deserialize { exceptionToThrow = new MsalServiceException( MsalError.NonParsableOAuthError, MsalErrorMessage.NonParsableOAuthError) { HttpResponse = response }; } catch (Exception ex) { exceptionToThrow = new MsalServiceException(MsalError.UnknownError, response.Body, ex) { HttpResponse = response }; } if (exceptionToThrow == null) { exceptionToThrow = new MsalServiceException( response.StatusCode == HttpStatusCode.NotFound ? MsalError.HttpStatusNotFound : MsalError.HttpStatusCodeNotOk, httpErrorCodeMessage) { HttpResponse = response }; } if (shouldLogAsError) { requestContext.Logger.ErrorPii(exceptionToThrow); } else { requestContext.Logger.InfoPii(exceptionToThrow); } throw exceptionToThrow; }
public async Task UsernamePasswordInvalidClientTestAsync() { using (var httpManager = new MockHttpManager()) { httpManager.AddInstanceDiscoveryMockHandler(); httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityCommonTenant); // user realm discovery httpManager.AddMockHandler( new MockHttpMessageHandler { ExpectedMethod = HttpMethod.Get, ResponseMessage = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent( "{\"ver\":\"1.0\",\"account_type\":\"Managed\",\"domain_name\":\"id.com\"}") }, ExpectedQueryParams = new Dictionary <string, string> { { "api-version", "1.0" } } }); // AAD httpManager.AddMockHandler( new MockHttpMessageHandler { ExpectedUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token", ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateInvalidClientResponseMessage() }); PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); // Call acquire token MsalServiceException result = await Assert.ThrowsExceptionAsync <MsalServiceException>( () => app.AcquireTokenByUsernamePassword( TestConstants.s_scope, TestConstants.s_user.Username, _secureString).ExecuteAsync()).ConfigureAwait(false); // Check inner exception Assert.AreEqual(MsalError.InvalidClient, result.ErrorCode); // There should be no cached entries. Assert.AreEqual(0, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); } }
public void OAuthClient_FailsWithServiceExceptionWhenItCanParseJsonResponse() { ValidateOathClient( MockHelpers.CreateTooManyRequestsJsonResponse(), exception => { MsalServiceException serverEx = exception.InnerException as MsalServiceException; Assert.IsNotNull(serverEx); Assert.AreEqual(429, serverEx.StatusCode); Assert.AreEqual(MockHelpers.TestRetryAfterDuration, serverEx.Headers.RetryAfter.Delta); Assert.AreEqual("Server overload", serverEx.ErrorCode); }); }
public async Task OAuthClient_FailsWithServiceExceptionWhenItCanParseJsonResponse_Async() { await ValidateOathClientAsync( MockHelpers.CreateTooManyRequestsJsonResponse(), exception => { MsalServiceException serverEx = exception as MsalServiceException; Assert.IsNotNull(serverEx); Assert.AreEqual(429, serverEx.StatusCode); Assert.AreEqual(MockHelpers.TestRetryAfterDuration, serverEx.Headers.RetryAfter.Delta); Assert.AreEqual("Server overload", serverEx.ErrorCode); }).ConfigureAwait(false); }
public void RecordException( AuthenticationRequestParameters requestParams, IReadOnlyDictionary <string, string> bodyParams, MsalServiceException ex) { if (!(ex is MsalThrottledServiceException)) { foreach (var provider in ThrottlingProviders) { provider.RecordException(requestParams, bodyParams, ex); } } }
public void MsalServiceException_HttpResponse_OAuthResponse() { // Arrange int statusCode = 400; string innerExMsg = "innerExMsg"; var innerException = new NotImplementedException(innerExMsg); HttpResponse httpResponse = new HttpResponse() { Body = jsonError, StatusCode = HttpStatusCode.BadRequest, // 400 }; // Act var msalException = new MsalServiceException(ExCode, ExMessage, innerException) { HttpResponse = httpResponse }; // Assert var msalServiceException = msalException as MsalServiceException; Assert.AreEqual(innerException, msalServiceException.InnerException); Assert.AreEqual(ExCode, msalServiceException.ErrorCode); Assert.AreEqual(jsonError, msalServiceException.ResponseBody); Assert.AreEqual(ExMessage, msalServiceException.Message); Assert.AreEqual(statusCode, msalServiceException.StatusCode); Assert.AreEqual("some_claims", msalServiceException.Claims); Assert.AreEqual("6347d33d-941a-4c35-9912-a9cf54fb1b3e", msalServiceException.CorrelationId); Assert.AreEqual("some_suberror", msalServiceException.SubError); // Act string piiMessage = MsalLogger.GetPiiScrubbedExceptionDetails(msalException); // Assert Assert.IsFalse(string.IsNullOrEmpty(piiMessage)); Assert.IsTrue( piiMessage.Contains(typeof(MsalServiceException).Name), "The pii message should contain the exception type"); Assert.IsTrue( piiMessage.Contains(typeof(NotImplementedException).Name), "The pii message should have the inner exception type"); Assert.IsTrue(piiMessage.Contains(ExCode)); Assert.IsTrue(piiMessage.Contains("6347d33d-941a-4c35-9912-a9cf54fb1b3e")); // Correlation Id Assert.IsFalse(piiMessage.Contains(ExMessage)); Assert.IsFalse(piiMessage.Contains(innerExMsg)); }
/// <summary> /// Constructor /// </summary> public MsalThrottledServiceException(MsalServiceException originalException) : base( originalException.ErrorCode, originalException.Message, originalException.InnerException) { SubError = originalException.SubError; StatusCode = originalException.StatusCode; Claims = originalException.Claims; CorrelationId = originalException.CorrelationId; ResponseBody = originalException.ResponseBody; Headers = originalException.Headers; OriginalServiceException = originalException; }
/// ----------------------------------------------------------------------------------------------------------------------------------------------------------------- /// /// /// GetAuthGatewayUserLoginSavedCredential Method (Saved Credential) /// public async Task <Microsoft.Identity.Client.AuthenticationResult> GetAuthGatewayUserLoginSavedCredential() { Microsoft.Identity.Client.AuthenticationResult authResult = null; AuthorityURI = defaultAuthorityURI + AzureTenantID; try { Console.WriteLine(" Authority URI: " + AuthorityURI); Console.WriteLine(" Resource URI: " + PowerBIResourceURI); Console.WriteLine(" Application ID: " + GatewayMgmtApplicationID); Console.WriteLine(" Access Scope: " + PowerBIAccessScope); Console.WriteLine(" Username: "******"", Password).SecurePassword; var accessTokenRequest = publicClient.AcquireTokenByUsernamePassword(scopes, UserName, PasswordSecure); authResult = await accessTokenRequest.ExecuteAsync(); } catch (AggregateException ex) { MsalServiceException ex1 = (MsalServiceException)ex.GetBaseException(); Console.WriteLine(" - Error acquiring token with ApplicationID/Secret (User/Pass) [GatewayMgmt]. "); Console.WriteLine(" Usually this is due to an invalid password"); Console.WriteLine(""); Console.WriteLine(" Details: " + ex1.StatusCode + ": " + ex1.ResponseBody); } catch (Exception ex) { Console.WriteLine(" - Error acquiring token with ApplicationID/Secret (User/pass) [GatewayMgmt]. "); Console.WriteLine(" Usually this is due to an invalid password"); Console.WriteLine(""); Console.WriteLine(" Details: " + ex.ToString()); } return(authResult); }
/// ----------------------------------------------------------------------------------------------------------------------------------------------------------------- /// /// /// GetAuthUserLoginSavedSPN Method (Saved SPN Auth) /// public async Task <Microsoft.Identity.Client.AuthenticationResult> GetAuthUserLoginSavedSPN() { Microsoft.Identity.Client.AuthenticationResult authResult = null; try { Console.WriteLine(" Authority URI: " + MSALAuthorityURI); Console.WriteLine(" Resource URI: " + PowerBIResourceURI); Console.WriteLine(" Application ID: " + ApplicationID); Console.WriteLine(" Access Scope: " + PowerBIAccessScope); //Console.WriteLine(" Client Secret: " + ClientSecret); // Build the access scope list List <string> scopes = new List <string>(); scopes.Add(PowerBIAccessScope); // Build the authentication request client var confidentialClient = ConfidentialClientApplicationBuilder .Create(ApplicationID) .WithClientSecret(ClientSecret) .WithAuthority(new Uri(MSALAuthorityURI)) .WithRedirectUri(PowerBIRedirectURI) .Build(); // Request an access token with the request client and scope var accessTokenRequest = confidentialClient.AcquireTokenForClient(scopes); authResult = await accessTokenRequest.ExecuteAsync(); } catch (AggregateException ex) { MsalServiceException ex1 = (MsalServiceException)ex.GetBaseException(); Console.WriteLine(" - Error acquiring token with ApplicationID/Secret (SPN)."); Console.WriteLine(" Usually this is due to an invalid Application (client) ID or Client Secret"); Console.WriteLine(""); Console.WriteLine(" Details: " + ex1.StatusCode + ": " + ex1.ResponseBody); } catch (Exception ex) { Console.WriteLine(" - Error acquiring token with ApplicationID/Secret (SPN)."); Console.WriteLine(" Usually this is due to an invalid Application (client) ID or Client Secret"); Console.WriteLine(""); Console.WriteLine(" Details: " + ex.Message.ToString()); } return(authResult); }
private static Exception ExtractErrorsFromTheResponse(HttpResponse response, ref bool shouldLogAsError) { Exception exceptionToThrow = null; // In cases where the end-point is not found (404) response.body will be empty. if (string.IsNullOrWhiteSpace(response.Body)) { return(null); } var msalTokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body); if (msalTokenResponse?.Error == null) { return(null); } if (MsalError.InvalidGrantError.Equals(msalTokenResponse.Error, StringComparison.OrdinalIgnoreCase)) { exceptionToThrow = new MsalUiRequiredException( MsalError.InvalidGrantError, msalTokenResponse.ErrorDescription) { HttpResponse = response }; } else { exceptionToThrow = new MsalServiceException( msalTokenResponse.Error, msalTokenResponse.ErrorDescription) { HttpResponse = response }; } // For device code flow, AuthorizationPending can occur a lot while waiting // for the user to auth via browser and this causes a lot of error noise in the logs. // So suppress this particular case to an Info so we still see the data but don't // log it as an error since it's expected behavior while waiting for the user. if (string.Compare(msalTokenResponse.Error, OAuth2Error.AuthorizationPending, StringComparison.OrdinalIgnoreCase) == 0) { shouldLogAsError = false; } return(exceptionToThrow); }
public void MockConfidentialClientApplication_Exception() { // Setup up a confidential client application that returns throws var mockApp = Substitute.For <IConfidentialClientApplication>(); mockApp .WhenForAnyArgs(x => x.AcquireTokenForClientAsync(Arg.Any <string[]>())) .Do(x => { throw new MsalServiceException("my error code", "my message"); }); // Now call the substitute and check the exception is thrown MsalServiceException ex = AssertException.Throws <MsalServiceException>(() => mockApp.AcquireTokenForClientAsync(new string[] { "scope1" })); Assert.AreEqual("my error code", ex.ErrorCode); Assert.AreEqual("my message", ex.Message); }