internal void ExceptionHandler(Exception exception) { var _exception = exception.GetBaseException() as ODataErrorException; AdalServiceException _serviceException = exception.GetBaseException() as AdalServiceException; var _innerException = _exception.InnerException; if (_exception != null) { throw new TIPException( new Error { Code = _exception.Error.ErrorCode, Message = _exception.Message, }, _exception.InnerException); } throw new TIPException( new Error { Code = _exception.Error.ErrorCode, Message = _exception.Message, }, _exception.InnerException); }
private RetryParams ComputeAdalRetry(Exception ex) { if (ex is AdalServiceException) { AdalServiceException adalServiceException = (AdalServiceException)ex; // When the Service Token Server (STS) is too busy because of “too many requests”, // it returns an HTTP error 429 with a hint about when you can try again (Retry-After response field) as a delay in seconds if (adalServiceException.ErrorCode == MsalTemporarilyUnavailable || adalServiceException.StatusCode == 429) { RetryConditionHeaderValue retryAfter = adalServiceException.Headers.RetryAfter; // Depending on the service, the recommended retry time may be in retryAfter.Delta or retryAfter.Date. Check both. if (retryAfter != null && retryAfter.Delta.HasValue) { return(new RetryParams(retryAfter.Delta.Value)); } else if (retryAfter != null && retryAfter.Date.HasValue) { return(new RetryParams(retryAfter.Date.Value.Offset)); } // We got a 429 but didn't get a specific back-off time. Use the default return(RetryParams.DefaultBackOff(0)); } } return(RetryParams.DefaultBackOff(0)); }
public string Authenticate(Uri requestUri, Uri callbackUri) { string key = requestUri.AbsoluteUri + callbackUri.AbsoluteUri; string value = null; if (IOMap.ContainsKey(key)) { value = IOMap[key]; if (value[0] == 'P') { return(value.Substring(1)); } if (value[0] == 'A') { string [] segments = value.Substring(1).Split(new [] { Delimiter }, StringSplitOptions.RemoveEmptyEntries); throw new AdalServiceException(errorCode: segments[0], message: segments[1]) { StatusCode = int.Parse(segments[2]) }; } } try { string result = this.internalWebUI.Authenticate(requestUri, callbackUri); value = 'P' + result; return(result); } catch (AdalException ex) { AdalServiceException serviceException = ex as AdalServiceException; if (serviceException != null && serviceException.StatusCode == 503) { value = null; } else { value = 'A' + string.Format("{0}{1}{2}{3}{4}", ex.ErrorCode, Delimiter, ex.Message, Delimiter, (serviceException != null) ? serviceException.StatusCode : 0); } throw; } finally { if (value != null) { IOMap.Add(key, value); } } }
private bool IsAdalServiceUnavailable(Exception ex) { AdalServiceException adalServiceException = ex as AdalServiceException; if (adalServiceException == null) { return(false); } // When the Service Token Server (STS) is too busy because of “too many requests”, // it returns an HTTP error 429 return(adalServiceException.ErrorCode == AdalError.ServiceUnavailable || adalServiceException.StatusCode == 429); }
private static bool IsAdalServiceUnavailable(Exception ex) { AdalServiceException adalServiceException = ex as AdalServiceException; if (adalServiceException == null) { return(false); } // When the Service Token Server (STS) is too busy because of “too many requests”, // it returns an HTTP error 429 return(adalServiceException.ErrorCode == MsalTemporarilyUnavailable || adalServiceException.StatusCode == HttpTooManyRequests); }
public void WsTrustRequestAcceptedByService() { AuthenticationContext context = new AuthenticationContext("https://login.microsoftonline.com/common", true); AdalServiceException ex = AssertException.TaskThrows <AdalServiceException>(() => context.AcquireTokenAsync("https://graph.windows.net", "unknown-client-F1E93291-6F42-453A-866F-C2F672F283BD", new UserCredential("*****@*****.**"))); Debug.WriteLine($"Error code: {ex.ErrorCode}"); Debug.WriteLine($"Error message: {ex.Message}"); // If the request is not well-formed then the error message returned will be something like // "Federated service at https://msft.sts.microsoft.com/adfs/services/trust/13/windowstransport returned error: ID3035: The request was not valid or is malformed." Assert.IsFalse(ex.Message.Contains("ID3035"), "Not expecting the request to be rejected as invalid"); }
private void HandleAdalServiceException(AdalServiceException e, IAADLogger Logger) { // Exception: AdalServiceException // Represents an error produced by the STS. // e.ErrorCode contains the error code and description, which can be used for debugging. // NOTE: Do not code a dependency on the contents of the error description, as it can change over time. // Design time consideration: Certain errors may be caused at development and exposed through this exception. // Looking inside the description will give more guidance on resolving the specific issue. // Action: Case 1: Non-Retryable // Do not perform an immediate retry. Only retry after user action. // Example Errors: default case Logger.Log($"AdalServiceException Message: {e.Message}"); Logger.Log($"AdalServiceException Status Code: {e.StatusCode.ToString()}"); }
private async Task <AuthenticationResultEx> RefreshAccessTokenAsync(AuthenticationResultEx result) { AuthenticationResultEx newResultEx = null; if (this.Resource != null) { var msg = "Refreshing access token..."; CallState.Logger.Verbose(this.CallState, msg); CallState.Logger.VerbosePii(this.CallState, msg); try { newResultEx = await this.SendTokenRequestByRefreshTokenAsync(result.RefreshToken) .ConfigureAwait(false); this.Authenticator.UpdateTenantId(result.Result.TenantId); newResultEx.Result.Authority = Authenticator.Authority; if (newResultEx.Result.IdToken == null) { // If Id token is not returned by token endpoint when refresh token is redeemed, we should copy tenant and user information from the cached token. newResultEx.Result.UpdateTenantAndUserInfo(result.Result.TenantId, result.Result.IdToken, result.Result.UserInfo); } } catch (AdalException ex) { AdalServiceException serviceException = ex as AdalServiceException; if (serviceException != null && serviceException.ErrorCode == "invalid_request") { throw new AdalServiceException( AdalError.FailedToRefreshToken, AdalErrorMessage.FailedToRefreshToken + ". " + serviceException.Message, serviceException.ServiceErrorCodes, serviceException); } newResultEx = new AuthenticationResultEx { Exception = ex }; } } return(newResultEx); }
public void NegativeDeviceCodeTest() { MockHttpMessageHandler mockMessageHandler = new MockHttpMessageHandler(TestConstants.DefaultAuthorityHomeTenant) { Method = HttpMethod.Get, Url = TestConstants.DefaultAuthorityHomeTenant + "oauth2/devicecode", ResponseMessage = MockHelpers.CreateDeviceCodeErrorResponse() }; HttpMessageHandlerFactory.AddMockHandler(mockMessageHandler); TokenCache cache = new TokenCache(); AuthenticationContext ctx = new AuthenticationContext(TestConstants.DefaultAuthorityHomeTenant, cache); DeviceCodeResult dcr; AdalServiceException ex = AssertException.TaskThrows <AdalServiceException>(async() => dcr = await ctx.AcquireDeviceCodeAsync("some-resource", "some-client").ConfigureAwait(false)); Assert.IsTrue(ex.Message.Contains("some error message")); }
public async Task NegativeDeviceCodeTimeoutTestAsync() { MockHttpMessageHandler mockMessageHandler = new MockHttpMessageHandler(TestConstants.DefaultAuthorityHomeTenant) { Method = HttpMethod.Get, Url = TestConstants.DefaultAuthorityHomeTenant + "oauth2/devicecode", ResponseMessage = MockHelpers.CreateSuccessDeviceCodeResponseMessage("1") }; HttpMessageHandlerFactory.AddMockHandler(mockMessageHandler); mockMessageHandler = new MockHttpMessageHandler(TestConstants.DefaultAuthorityHomeTenant) { Method = HttpMethod.Post, Url = TestConstants.DefaultAuthorityHomeTenant + "oauth2/token", ResponseMessage = MockHelpers.CreateFailureResponseMessage("{\"error\":\"authorization_pending\"," + "\"error_description\":\"AADSTS70016: Pending end-user authorization." + "\\r\\nTrace ID: f6c2c73f-a21d-474e-a71f-d8b121a58205\\r\\nCorrelation ID: " + "36fe3e82-442f-4418-b9f4-9f4b9295831d\\r\\nTimestamp: 2015-09-24 19:51:51Z\"," + "\"error_codes\":[70016],\"timestamp\":\"2015-09-24 19:51:51Z\",\"trace_id\":" + "\"f6c2c73f-a21d-474e-a71f-d8b121a58205\",\"correlation_id\":" + "\"36fe3e82-442f-4418-b9f4-9f4b9295831d\"}") }; HttpMessageHandlerFactory.AddMockHandler(mockMessageHandler); mockMessageHandler = new MockHttpMessageHandler(TestConstants.DefaultAuthorityHomeTenant) { Method = HttpMethod.Post, Url = TestConstants.DefaultAuthorityHomeTenant + "oauth2/token", ResponseMessage = MockHelpers.CreateDeviceCodeExpirationErrorResponse() }; HttpMessageHandlerFactory.AddMockHandler(mockMessageHandler); TokenCache cache = new TokenCache(); AuthenticationContext ctx = new AuthenticationContext(TestConstants.DefaultAuthorityHomeTenant, cache); DeviceCodeResult dcr = await ctx.AcquireDeviceCodeAsync("some resource", "some authority").ConfigureAwait(false); Assert.IsNotNull(dcr); AuthenticationResult result; AdalServiceException ex = AssertException.TaskThrows <AdalServiceException>(async() => result = await ctx.AcquireTokenByDeviceCodeAsync(dcr).ConfigureAwait(false)); Assert.IsTrue(ex.Message.Contains("Verification code expired")); }
private async Task <T> GetResponseAsync <T>(bool respondToDeviceAuthChallenge) { T typedResponse = default(T); IHttpWebResponse response; try { IDictionary <string, string> adalIdHeaders = AdalIdHelper.GetAdalIdParameters(); foreach (KeyValuePair <string, string> kvp in adalIdHeaders) { this.Client.Headers[kvp.Key] = kvp.Value; } //add pkeyauth header this.Client.Headers[DeviceAuthHeaderName] = DeviceAuthHeaderValue; using (response = await this.Client.GetResponseAsync().ConfigureAwait(false)) { typedResponse = EncodingHelper.DeserializeResponse <T>(response.ResponseString); } } catch (HttpRequestWrapperException ex) { if (ex.InnerException is TaskCanceledException) { Resiliency = true; _callState.Logger.Information(this.CallState, "Network timeout, Exception type: " + ex.InnerException.GetType()); _callState.Logger.InformationPii(this.CallState, "Network timeout, Exception message: " + ex.InnerException.Message); } if (!Resiliency && ex.WebResponse == null) { _callState.Logger.Error(CallState, ex); _callState.Logger.ErrorPii(CallState, ex); throw new AdalServiceException(AdalError.Unknown, ex); } //check for resiliency if (!Resiliency && (int)ex.WebResponse.StatusCode >= 500 && (int)ex.WebResponse.StatusCode < 600) { _callState.Logger.Information(this.CallState, "HttpStatus code: " + ex.WebResponse.StatusCode + ", Exception type: " + ex.InnerException?.GetType()); _callState.Logger.InformationPii(this.CallState, "HttpStatus code: " + ex.WebResponse.StatusCode + ", Exception message: " + ex.InnerException?.Message); Resiliency = true; } if (Resiliency) { if (RetryOnce) { await Task.Delay(DelayTimePeriodMilliSeconds).ConfigureAwait(false); RetryOnce = false; var msg = "Retrying one more time.."; _callState.Logger.Information(this.CallState, msg); _callState.Logger.InformationPii(this.CallState, msg); return(await this.GetResponseAsync <T>(respondToDeviceAuthChallenge).ConfigureAwait(false)); } _callState.Logger.Information(CallState, "Retry Failed, Exception type: " + ex.InnerException?.GetType()); _callState.Logger.InformationPii(CallState, "Retry Failed, Exception message: " + ex.InnerException?.Message); } if (!this.IsDeviceAuthChallenge(ex.WebResponse, respondToDeviceAuthChallenge)) { TokenResponse tokenResponse = TokenResponse.CreateFromErrorResponse(ex.WebResponse); string[] errorCodes = tokenResponse.ErrorCodes ?? new[] { ex.WebResponse.StatusCode.ToString() }; AdalServiceException serviceEx = new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription, errorCodes, ex); if (ex.WebResponse.StatusCode == HttpStatusCode.BadRequest && tokenResponse.Error == AdalError.InteractionRequired) { throw new AdalClaimChallengeException(tokenResponse.Error, tokenResponse.ErrorDescription, ex, tokenResponse.Claims); } throw serviceEx; } //attempt device auth return(await HandleDeviceAuthChallenge <T>(ex.WebResponse).ConfigureAwait(false)); } return(typedResponse); }
public LoginFailedException(AdalServiceException innerException) : base(innerException.Message, innerException) { }