private async Task <AuthenticationResult> RefreshAccessTokenAsync(AuthenticationResult result) { AuthenticationResult newResult = null; if (this.Resource != null) { try { newResult = await this.SendTokenRequestByRefreshTokenAsync(result.RefreshToken); this.Authenticator.UpdateTenantId(result.TenantId); if (newResult.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. newResult.UpdateTenantAndUserInfo(result.TenantId, result.IdToken, 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, (WebException)serviceException.InnerException); } newResult = null; } } return(newResult); }
private void VerifyAuthorizationResult() { if (this.promptBehavior == PromptBehavior.Never && this.authorizationResult.Error == OAuthError.LoginRequired) { var ex = new AdalException(AdalError.UserInteractionRequired); Logger.LogException(this.CallState, ex); throw ex; } if (this.authorizationResult.Status != AuthorizationStatus.Success) { var ex = new AdalServiceException(this.authorizationResult.Error, this.authorizationResult.ErrorDescription); Logger.LogException(this.CallState, ex); throw ex; } }
private static async Task <AuthenticationParameters> CreateFromResourceUrlCommonAsync(Uri resourceUrl) { CallState callState = new CallState(Guid.NewGuid(), false); if (resourceUrl == null) { throw new ArgumentNullException("resourceUrl"); } IHttpWebResponse response = null; AuthenticationParameters authParams; try { IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(resourceUrl.AbsoluteUri); request.ContentType = "application/x-www-form-urlencoded"; response = await request.GetResponseSyncOrAsync(callState); var ex = new AdalException(AdalError.UnauthorizedResponseExpected); Logger.Error(null, ex); throw ex; } catch (WebException ex) { response = NetworkPlugin.HttpWebRequestFactory.CreateResponse(ex.Response); if (response == null) { var serviceEx = new AdalServiceException(AdalErrorMessage.UnauthorizedHttpStatusCodeExpected, ex); Logger.Error(null, serviceEx); throw serviceEx; } authParams = CreateFromUnauthorizedResponseCommon(response); } finally { if (response != null) { response.Close(); } } return(authParams); }
private async Task <AuthenticationResultEx> RefreshAccessTokenAsync(AuthenticationResultEx result) { AuthenticationResultEx newResultEx = null; if (this.Resource != null) { CallState.Logger.Verbose(this.CallState, "Refreshing access token..."); 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); }
internal static async Task <UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState) { string userRealmEndpoint = userRealmUri; userRealmEndpoint += (userName + "?api-version=1.0"); userRealmEndpoint = HttpHelper.CheckForExtraQueryParameter(userRealmEndpoint); Logger.Information(callState, "Sending user realm discovery request to '{0}'", userRealmEndpoint); UserRealmDiscoveryResponse userRealmResponse; ClientMetrics clientMetrics = new ClientMetrics(); try { IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(userRealmEndpoint); request.Method = "GET"; request.Accept = "application/json"; HttpHelper.AddCorrelationIdHeadersToRequest(request, callState); AdalIdHelper.AddAsHeaders(request); clientMetrics.BeginClientMetricsRecord(request, callState); using (var response = await request.GetResponseSyncOrAsync(callState)) { HttpHelper.VerifyCorrelationIdHeaderInReponse(response, callState); userRealmResponse = HttpHelper.DeserializeResponse <UserRealmDiscoveryResponse>(response); clientMetrics.SetLastError(null); } } catch (WebException ex) { var serviceException = new AdalServiceException(AdalError.UserRealmDiscoveryFailed, ex); clientMetrics.SetLastError(new[] { serviceException.StatusCode.ToString() }); throw serviceException; } finally { clientMetrics.EndClientMetricsRecord(ClientMetricsEndpointType.UserRealmDiscovery, callState); } return(userRealmResponse); }
internal static async Task<UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState) { string userRealmEndpoint = userRealmUri; userRealmEndpoint += (userName + "?api-version=1.0"); userRealmEndpoint = HttpHelper.CheckForExtraQueryParameter(userRealmEndpoint); Logger.Information(callState, "Sending user realm discovery request to '{0}'", userRealmEndpoint); UserRealmDiscoveryResponse userRealmResponse; ClientMetrics clientMetrics = new ClientMetrics(); try { IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(userRealmEndpoint); request.Method = "GET"; request.Accept = "application/json"; HttpHelper.AddCorrelationIdHeadersToRequest(request, callState); AdalIdHelper.AddAsHeaders(request); clientMetrics.BeginClientMetricsRecord(request, callState); using (var response = await request.GetResponseSyncOrAsync(callState)) { HttpHelper.VerifyCorrelationIdHeaderInReponse(response, callState); userRealmResponse = HttpHelper.DeserializeResponse<UserRealmDiscoveryResponse>(response); clientMetrics.SetLastError(null); } } catch (WebException ex) { var serviceException = new AdalServiceException(AdalError.UserRealmDiscoveryFailed, ex); clientMetrics.SetLastError(new[] { serviceException.StatusCode.ToString() }); throw serviceException; } finally { clientMetrics.EndClientMetricsRecord(ClientMetricsEndpointType.UserRealmDiscovery, callState); } return userRealmResponse; }
private async Task <T> GetResponseAsync <T>(bool respondToDeviceAuthChallenge) { T typedResponse = default(T); IHttpWebResponse response; try { if (PlatformPlugin.HttpClientFactory.AddAdditionalHeaders) { 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; PlatformPlugin.Logger.Information(this.CallState, "Network timeout - " + ex.InnerException.Message); } if (!this.isDeviceAuthChallenge(ex.WebResponse, respondToDeviceAuthChallenge)) { AdalServiceException serviceEx; if (ex.WebResponse != null) { TokenResponse tokenResponse = TokenResponse.CreateFromErrorResponse(ex.WebResponse); string[] errorCodes = tokenResponse.ErrorCodes ?? new[] { ex.WebResponse.StatusCode.ToString() }; serviceEx = new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription, errorCodes, ex); if ((int)ex.WebResponse.StatusCode >= 500 && (int)ex.WebResponse.StatusCode < 600) { PlatformPlugin.Logger.Information(this.CallState, "HttpStatus code: " + ex.WebResponse.StatusCode + " - " + ex.InnerException.Message); Resiliency = true; } } else { serviceEx = new AdalServiceException(AdalError.Unknown, ex); } if (Resiliency) { if (RetryOnce) { await Task.Delay(DelayTimePeriodMilliSeconds).ConfigureAwait(false); RetryOnce = false; PlatformPlugin.Logger.Information(this.CallState, "Retrying one more time.."); return(await this.GetResponseAsync <T>(respondToDeviceAuthChallenge).ConfigureAwait(false)); } PlatformPlugin.Logger.Information(this.CallState, "Retry Failed - " + ex.InnerException.Message); } PlatformPlugin.Logger.Error(CallState, serviceEx); throw serviceEx; } else { response = ex.WebResponse; } } //check for pkeyauth challenge if (this.isDeviceAuthChallenge(response, respondToDeviceAuthChallenge)) { return(await HandleDeviceAuthChallenge <T>(response).ConfigureAwait(false)); } return(typedResponse); }
public static AuthenticationResult ParseTokenResponse(TokenResponse tokenResponse, CallState callState) { AuthenticationResult result; if (tokenResponse.AccessToken != null) { DateTimeOffset expiresOn = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn); result = new AuthenticationResult(tokenResponse.TokenType, tokenResponse.AccessToken, tokenResponse.RefreshToken, expiresOn) { // This is only needed for AcquireTokenByAuthorizationCode in which parameter resource is optional and we need // to get it from the STS response. Resource = tokenResponse.Resource, IsMultipleResourceRefreshToken = (!string.IsNullOrWhiteSpace(tokenResponse.RefreshToken) && !string.IsNullOrWhiteSpace(tokenResponse.Resource)), }; IdToken idToken = ParseIdToken(tokenResponse.IdToken); if (idToken != null) { string tenantId = idToken.TenantId; string uniqueId = null; string displayableId = null; if (!string.IsNullOrWhiteSpace(idToken.ObjectId)) { uniqueId = idToken.ObjectId; } else if (!string.IsNullOrWhiteSpace(idToken.Subject)) { uniqueId = idToken.Subject; } if (!string.IsNullOrWhiteSpace(idToken.UPN)) { displayableId = idToken.UPN; } else if (!string.IsNullOrWhiteSpace(idToken.Email)) { displayableId = idToken.Email; } string givenName = idToken.GivenName; string familyName = idToken.FamilyName; string identityProvider = idToken.IdentityProvider ?? idToken.Issuer; DateTimeOffset?passwordExpiresOffest = null; if (idToken.PasswordExpiration > 0) { passwordExpiresOffest = DateTime.UtcNow + TimeSpan.FromSeconds(idToken.PasswordExpiration); } Uri changePasswordUri = null; if (!string.IsNullOrEmpty(idToken.PasswordChangeUrl)) { changePasswordUri = new Uri(idToken.PasswordChangeUrl); } result.UpdateTenantAndUserInfo(tenantId, tokenResponse.IdToken, new UserInfo { UniqueId = uniqueId, DisplayableId = displayableId, GivenName = givenName, FamilyName = familyName, IdentityProvider = identityProvider, PasswordExpiresOn = passwordExpiresOffest, PasswordChangeUrl = changePasswordUri }); } } else if (tokenResponse.Error != null) { var ex = new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription); PlatformPlugin.Logger.LogException(callState, ex); throw ex; } else { var ex = new AdalServiceException(AdalError.Unknown, AdalErrorMessage.Unknown); PlatformPlugin.Logger.LogException(callState, ex); throw ex; } return(result); }
public async Task TimeoutTest() { const string TestServiceUrl = "http://localhost:8080"; using (WebApp.Start<TestService>(TestServiceUrl)) { HttpClientWrapper webClient = new HttpClientWrapper(TestServiceUrl + "?delay=0&response_code=200", null) { TimeoutInMilliSeconds = 10000 }; await webClient.GetResponseAsync(); webClient = new HttpClientWrapper(TestServiceUrl + "?delay=0&response_code=200", null) { TimeoutInMilliSeconds = 10000 }; await webClient.GetResponseAsync(); try { webClient = new HttpClientWrapper(TestServiceUrl + "?delay=0&response_code=400", null) { TimeoutInMilliSeconds = 10000 }; await webClient.GetResponseAsync(); } catch (HttpRequestWrapperException ex) { Verify.AreEqual(ex.WebResponse.StatusCode, HttpStatusCode.BadRequest); } try { webClient = new HttpClientWrapper(TestServiceUrl + "?delay=10000&response_code=200", null) { TimeoutInMilliSeconds = 500 }; await webClient.GetResponseAsync(); } catch (HttpRequestWrapperException ex) { Verify.IsTrue(ex.InnerException is TaskCanceledException); var serviceException = new AdalServiceException(AdalError.Unknown, ex); Verify.AreEqual(serviceException.StatusCode, (int)HttpStatusCode.RequestTimeout); } } }
private static async Task<AuthenticationParameters> CreateFromResourceUrlCommonAsync(Uri resourceUrl) { CallState callState = new CallState(Guid.NewGuid(), false); if (resourceUrl == null) { throw new ArgumentNullException("resourceUrl"); } IHttpWebResponse response = null; AuthenticationParameters authParams; try { IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(resourceUrl.AbsoluteUri); request.ContentType = "application/x-www-form-urlencoded"; response = await request.GetResponseSyncOrAsync(callState); var ex = new AdalException(AdalError.UnauthorizedResponseExpected); Logger.Error(null, ex); throw ex; } catch (WebException ex) { response = NetworkPlugin.HttpWebRequestFactory.CreateResponse(ex.Response); if (response == null) { var serviceEx = new AdalServiceException(AdalErrorMessage.UnauthorizedHttpStatusCodeExpected, ex); Logger.Error(null, serviceEx); throw serviceEx; } authParams = CreateFromUnauthorizedResponseCommon(response); } finally { if (response != null) { response.Close(); } } return authParams; }
private static async Task<AuthenticationParameters> CreateFromResourceUrlCommonAsync(Uri resourceUrl) { if (resourceUrl == null) { throw new ArgumentNullException("resourceUrl"); } AuthenticationParameters authParams; try { IHttpClient request = PlatformPlugin.HttpClientFactory.Create(resourceUrl.AbsoluteUri, null); using (await request.GetResponseAsync()) { var ex = new AdalException(AdalError.UnauthorizedResponseExpected); PlatformPlugin.Logger.Error(null, ex); throw ex; } } catch (HttpRequestWrapperException ex) { IHttpWebResponse response = ex.WebResponse; if (response == null) { var serviceEx = new AdalServiceException(AdalErrorMessage.UnauthorizedHttpStatusCodeExpected, ex); PlatformPlugin.Logger.Error(null, serviceEx); throw serviceEx; } authParams = CreateFromUnauthorizedResponseCommon(response); } return authParams; }
private async Task <T> GetResponseAsync <T>(string endpointType, bool respondToDeviceAuthChallenge) { T typedResponse = default(T); IHttpWebResponse response; ClientMetrics clientMetrics = new ClientMetrics(); try { clientMetrics.BeginClientMetricsRecord(this.CallState); if (PlatformPlugin.HttpClientFactory.AddAdditionalHeaders) { 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 = 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()) { typedResponse = DeserializeResponse <T>(response.ResponseStream); clientMetrics.SetLastError(null); } } catch (HttpRequestWrapperException ex) { if (!this.isDeviceAuthChallenge(endpointType, ex.WebResponse, respondToDeviceAuthChallenge)) { AdalServiceException serviceEx; if (ex.WebResponse != null) { TokenResponse tokenResponse = TokenResponse.CreateFromErrorResponse(ex.WebResponse); string[] errorCodes = tokenResponse.ErrorCodes ?? new[] { ex.WebResponse.StatusCode.ToString() }; serviceEx = new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription, errorCodes, ex); } else { serviceEx = new AdalServiceException(AdalError.Unknown, ex); } clientMetrics.SetLastError(serviceEx.ServiceErrorCodes); PlatformPlugin.Logger.Error(CallState, serviceEx); throw serviceEx; } else { response = ex.WebResponse; } } finally { clientMetrics.EndClientMetricsRecord(endpointType, this.CallState); } //check for pkeyauth challenge if (this.isDeviceAuthChallenge(endpointType, response, respondToDeviceAuthChallenge)) { return(await HandleDeviceAuthChallenge <T>(endpointType, response)); } return(typedResponse); }