public async Task<AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState) { returnedUriReady = new SemaphoreSlim(0); Authenticate(authorizationUri, redirectUri, callState); await returnedUriReady.WaitAsync(); return authorizationResult; }
public ReplayerHttpClient(string uri, CallState callState) { this.internalHttpCilent = (new HttpClientFactory()).Create(uri, null); this.keyElements = new Dictionary<string, string>(); this.keyElements["Uri"] = uri; this.CallState = callState; }
public AuthorizationResult ProcessAuthorizationResult(IWebAuthenticationBrokerContinuationEventArgs args, CallState callState) { AuthorizationResult result; switch (args.WebAuthenticationResult.ResponseStatus) { case WebAuthenticationStatus.Success: // Issue #129 - Windows Phone cannot handle ms-app URI's so use the placeholder URI for SSO var responseData = args.WebAuthenticationResult.ResponseData; if(responseData.StartsWith(Constant.MsAppScheme, StringComparison.OrdinalIgnoreCase)) { responseData = Constant.SsoPlaceHolderUri + responseData.Substring(responseData.IndexOf('?')); } result = OAuth2Response.ParseAuthorizeResponse(responseData, callState); break; case WebAuthenticationStatus.ErrorHttp: result = new AuthorizationResult(AdalError.AuthenticationFailed, args.WebAuthenticationResult.ResponseErrorDetail.ToString()); break; case WebAuthenticationStatus.UserCancel: result = new AuthorizationResult(AdalError.AuthenticationCanceled, AdalErrorMessage.AuthenticationCanceled); break; default: result = new AuthorizationResult(AdalError.AuthenticationFailed, AdalErrorMessage.AuthorizationServerInvalidResponse); break; } return result; }
public void BeginClientMetricsRecord(CallState callState) { if (callState != null && callState.AuthorityType == AuthorityType.AAD) { metricsTimer = Stopwatch.StartNew(); } }
internal static Uri ExtractWsTrustAddressFromMex(XDocument mexDocument, UserAuthType userAuthType, CallState callState) { Uri url; try { Dictionary<string, MexPolicy> policies = ReadPolicies(mexDocument); Dictionary<string, MexPolicy> bindings = ReadPolicyBindings(mexDocument, policies); SetPolicyEndpointAddresses(mexDocument, bindings); Random random = new Random(); MexPolicy policy = policies.Values.Where(p => p.Url != null && p.AuthType == userAuthType).OrderBy(p => random.Next()).FirstOrDefault(); if (policy != null) { url = policy.Url; } else if (userAuthType == UserAuthType.IntegratedAuth) { throw new AdalException(AdalError.IntegratedAuthFailed, new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument)); } else { throw new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument); } } catch (XmlException ex) { throw new AdalException(AdalError.ParsingWsMetadataExchangeFailed, ex); } return url; }
public override string GetRedirectUriAsString(Uri redirectUri, CallState callState) { string redirectUriString; if (ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri)) { try { redirectUriString = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().OriginalString; } catch (FormatException ex) { // This is the workaround for a bug in managed Uri class of WinPhone SDK which makes it throw UriFormatException when it gets called from unmanaged code. const string CurrentApplicationCallbackUriSetting = "CurrentApplicationCallbackUri"; if (ApplicationData.Current.LocalSettings.Values.ContainsKey(CurrentApplicationCallbackUriSetting)) { redirectUriString = (string)ApplicationData.Current.LocalSettings.Values[CurrentApplicationCallbackUriSetting]; } else { throw new AdalException(AdalErrorEx.NeedToSetCallbackUriAsLocalSetting, AdalErrorMessageEx.NeedToSetCallbackUriAsLocalSetting, ex); } } } else { redirectUriString = redirectUri.OriginalString; } return redirectUriString; }
public void BeginClientMetricsRecord(IHttpWebRequest request, CallState callState) { if (callState != null && callState.AuthorityType == AuthorityType.AAD) { AddClientMetricsHeadersToRequest(request); metricsTimer = Stopwatch.StartNew(); } }
public virtual Uri ValidateRedirectUri(Uri redirectUri, CallState callState) { if (redirectUri == null) { throw new ArgumentNullException("redirectUri"); } return redirectUri; }
internal static void Error(CallState callState, Exception ex) { string message = PrepareLogMessage(callState, GetCallerType(), "{0}", ex); AdalTrace.TraceSource.TraceEvent(TraceEventType.Error, 4, message); if (AdalTrace.LegacyTraceSwitch.TraceError) { Trace.TraceError(message); } }
internal static void Warning(CallState callState, string format, params object[] args) { string message = PrepareLogMessage(callState, GetCallerType(), format, args); AdalTrace.TraceSource.TraceEvent(TraceEventType.Warning, 3, message); if (AdalTrace.LegacyTraceSwitch.TraceWarning) { Trace.TraceWarning(message); } }
internal static void Information(CallState callState, string format, params object[] args) { string message = PrepareLogMessage(callState, GetCallerType(), format, args); AdalTrace.TraceSource.TraceData(TraceEventType.Information, 2, message); if (AdalTrace.LegacyTraceSwitch.TraceInfo) { Trace.TraceInformation(message); } }
public override Uri ValidateRedirectUri(Uri redirectUri, CallState callState) { if (redirectUri == null) { redirectUri = Constant.SsoPlaceHolderUri; PlatformPlugin.Logger.Verbose(callState, "ms-app redirect Uri is used"); } return redirectUri; }
internal static async Task<UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState) { string userRealmEndpoint = userRealmUri; userRealmEndpoint += (userName + "?api-version=1.0"); PlatformPlugin.Logger.Information(callState, string.Format("Sending user realm discovery request to '{0}'", userRealmEndpoint)); var client = new AdalHttpClient(userRealmEndpoint, callState) { Client = { Accept = "application/json" } }; return await client.GetResponseAsync<UserRealmDiscoveryResponse>(ClientMetricsEndpointType.UserRealmDiscovery); }
public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState) { try { WebAuthenticationBroker.AuthenticateAndContinue(authorizationUri, ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri) ? null : redirectUri, null, WebAuthenticationOptions.None); } catch (Exception ex) { throw new AdalException(AdalError.AuthenticationUiFailed, ex); } }
public override async Task<bool> IsUserLocalAsync(CallState callState) { WindowsIdentity current = WindowsIdentity.GetCurrent(); if (current != null) { string prefix = WindowsIdentity.GetCurrent().Name.Split('\\')[0].ToUpperInvariant(); return prefix.Equals(Environment.MachineName.ToUpperInvariant()); } return false; }
internal static void Verbose(CallState callState, string format, params object[] args) { string message = PrepareLogMessage(callState, GetCallerType(), format, args); AdalTrace.TraceSource.TraceEvent(TraceEventType.Verbose, 1, message); if (AdalTrace.LegacyTraceSwitch.TraceVerbose) { // There is no TraceVerbose method. Trace.TraceInformation(message); } }
public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState) { try { this.parameters.CallerViewController.PresentViewController(new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri, redirectUri.OriginalString, CallbackMethod), false, null); } catch (Exception ex) { throw new AdalException(AdalError.AuthenticationUiFailed, ex); } }
public async Task VerifyAnotherHostByInstanceDiscoveryAsync(string host, string tenant, CallState callState) { string instanceDiscoveryEndpoint = this.InstanceDiscoveryEndpoint; instanceDiscoveryEndpoint += ("?api-version=1.0&authorization_endpoint=" + AuthorizeEndpointTemplate); instanceDiscoveryEndpoint = instanceDiscoveryEndpoint.Replace("{host}", host); instanceDiscoveryEndpoint = instanceDiscoveryEndpoint.Replace("{tenant}", tenant); instanceDiscoveryEndpoint = HttpHelper.CheckForExtraQueryParameter(instanceDiscoveryEndpoint); ClientMetrics clientMetrics = new ClientMetrics(); try { IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(instanceDiscoveryEndpoint); request.Method = "GET"; HttpHelper.AddCorrelationIdHeadersToRequest(request, callState); AdalIdHelper.AddAsHeaders(request); clientMetrics.BeginClientMetricsRecord(request, callState); using (var response = await request.GetResponseSyncOrAsync(callState)) { HttpHelper.VerifyCorrelationIdHeaderInReponse(response, callState); InstanceDiscoveryResponse discoveryResponse = HttpHelper.DeserializeResponse<InstanceDiscoveryResponse>(response); clientMetrics.SetLastError(null); if (discoveryResponse.TenantDiscoveryEndpoint == null) { throw new AdalException(AdalError.AuthorityNotInValidList); } } } catch (WebException ex) { TokenResponse tokenResponse = OAuth2Response.ReadErrorResponse(ex.Response); clientMetrics.SetLastError(tokenResponse != null ? tokenResponse.ErrorCodes : null); if (tokenResponse.Error == "invalid_instance") { throw new AdalServiceException(AdalError.AuthorityNotInValidList, ex); } else { throw new AdalServiceException( AdalError.AuthorityValidationFailed, string.Format(CultureInfo.InvariantCulture, "{0}. {1}: {2}", AdalErrorMessage.AuthorityValidationFailed, tokenResponse.Error, tokenResponse.ErrorDescription), tokenResponse.ErrorCodes, ex); } } finally { clientMetrics.EndClientMetricsRecord(ClientMetricsEndpointType.InstanceDiscovery, callState); } }
public static async Task<WsTrustResponse> SendRequestAsync(WsTrustAddress wsTrustAddress, UserCredential credential, CallState callState) { IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(wsTrustAddress.Uri.AbsoluteUri); request.ContentType = "application/soap+xml;"; if (credential.UserAuthType == UserAuthType.IntegratedAuth) { SetKerberosOption(request); } StringBuilder messageBuilder = BuildMessage(DefaultAppliesTo, wsTrustAddress, credential); string soapAction = XmlNamespace.Issue.ToString(); if (wsTrustAddress.Version == WsTrustVersion.WsTrust2005) { soapAction = XmlNamespace.Issue2005.ToString(); } Dictionary<string, string> headers = new Dictionary<string, string> { { "SOAPAction", soapAction } }; WsTrustResponse wstResponse; try { HttpHelper.SetPostRequest(request, new RequestParameters(messageBuilder), callState, headers); IHttpWebResponse response = await request.GetResponseSyncOrAsync(callState); wstResponse = WsTrustResponse.CreateFromResponse(response.GetResponseStream(), wsTrustAddress.Version); } catch (WebException ex) { string errorMessage; try { XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.Response.GetResponseStream()); errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState); } catch (AdalException) { errorMessage = "See inner exception for detail."; } throw new AdalServiceException( AdalError.FederatedServiceReturnedError, string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, wsTrustAddress.Uri, errorMessage), null, ex); } return wstResponse; }
public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState) { try { var agentIntent = new Intent(this.parameters.CallerActivity, typeof(AuthenticationAgentActivity)); agentIntent.PutExtra("Url", authorizationUri.AbsoluteUri); agentIntent.PutExtra("Callback", redirectUri.OriginalString); this.parameters.CallerActivity.StartActivityForResult(agentIntent, 0); } catch (Exception ex) { throw new AdalException(AdalError.AuthenticationUiFailed, ex); } }
public Dictionary<string, string> GetPreviousRequestRecord(CallState callState) { Dictionary<string, string> parameters; if (callState != null && callState.AuthorityType == AuthorityType.AAD) { parameters = GetClientMetricsParameters(); } else { parameters = new Dictionary<string, string>(); } return parameters; }
public override async Task <bool> IsUserLocalAsync(CallState callState) { return(await Task.Factory.StartNew(() => { WindowsIdentity current = WindowsIdentity.GetCurrent(); if (current != null) { string prefix = WindowsIdentity.GetCurrent().Name.Split('\\')[0].ToUpperInvariant(); return prefix.Equals(Environment.MachineName.ToUpperInvariant()); } return false; }).ConfigureAwait(false)); }
public async Task <IHttpWebResponse> GetResponseSyncOrAsync(CallState callState) { if (this.BodyParameters != null) { using (Stream stream = await GetRequestStreamSyncOrAsync(callState)) { this.BodyParameters.WriteToStream(stream); } } #if ADAL_NET if (callState != null && callState.CallSync) { this.request.Timeout = this.timeoutInMilliSeconds; return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(this.request.GetResponse())); } Task <WebResponse> getResponseTask = this.request.GetResponseAsync(); System.Threading.ThreadPool.RegisterWaitForSingleObject( ((IAsyncResult)getResponseTask).AsyncWaitHandle, delegate(object state, bool timedOut) { if (timedOut) { ((HttpWebRequest)state).Abort(); } }, this.request, this.timeoutInMilliSeconds, true); return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(await getResponseTask)); #else var timer = Windows.System.Threading.ThreadPoolTimer.CreateTimer( delegate { this.request.Abort(); }, TimeSpan.FromMilliseconds(this.timeoutInMilliSeconds)); try { return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(await this.request.GetResponseAsync())); } finally { timer.Cancel(); } #endif }
internal override void Warning(CallState callState, string message, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "") { string log = PrepareLogMessage(callState, GetCallerFilename(callerFilePath), message); if (LoggerCallbackHandler.UseDefaultLogging) { #if NETSTANDARD1_3 Console.WriteLine(log); #else AdalEventSource.Warning(log); #endif } LoggerCallbackHandler.ExecuteCallback(LogLevel.Warning, log); }
public Dictionary <string, string> GetPreviousRequestRecord(CallState callState) { Dictionary <string, string> parameters; if (callState != null && callState.AuthorityType == AuthorityType.AAD) { parameters = GetClientMetricsParameters(); } else { parameters = new Dictionary <string, string>(); } return(parameters); }
public static void AddCorrelationIdHeadersToRequest(IHttpWebRequest request, CallState callState) { if (callState == null || callState.CorrelationId == Guid.Empty) { return; } Dictionary <string, string> headers = new Dictionary <string, string> { { OAuthHeader.CorrelationId, callState.CorrelationId.ToString() }, { OAuthHeader.RequestCorrelationIdInResponse, "true" } }; AddHeadersToRequest(request, headers); }
public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState) { try { var agentIntent = new Intent(this.parameters.CallerActivity, typeof(AuthenticationAgentActivity)); agentIntent.PutExtra("Url", authorizationUri.AbsoluteUri); agentIntent.PutExtra("Callback", redirectUri.AbsoluteUri); this.parameters.CallerActivity.StartActivityForResult(agentIntent, 0); } catch (Exception ex) { var adalEx = new AdalException(AdalError.AuthenticationUiFailed, ex); PlatformPlugin.Logger.LogException(callState, ex); throw adalEx; } }
public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState) { try { this.parameters.CallerViewController.InvokeOnMainThread(() => { var navigationController = new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri, redirectUri.OriginalString, CallbackMethod); this.parameters.CallerViewController.PresentViewController(navigationController, false, null); }); } catch (Exception ex) { throw new AdalException(AdalError.AuthenticationUiFailed, ex); } }
// This constructor is called by ContinueAcquireTokenAsync after WAB call has returned. public AcquireTokenInteractiveHandler(Authenticator authenticator, TokenCache tokenCache, IWebAuthenticationBrokerContinuationEventArgs args) : this( authenticator, tokenCache, (string)args.ContinuationData[WabArgName.Resource], (string)args.ContinuationData[WabArgName.ClientId], GetRedirectUri((string)args.ContinuationData[WabArgName.RedirectUri]), // Issue #129 - Windows Phone cannot handle ms-app URI's so use the placeholder URI for SSO PromptBehavior.Always, // This is simply to disable cache lookup. In fact, there is no authorize call at this point and promptBehavior is not applicable. new UserIdentifier((string)args.ContinuationData[WabArgName.UserId], (UserIdentifierType)((int)args.ContinuationData[WabArgName.UserIdType])), null, NetworkPlugin.WebUIFactory.Create(), false) { CallState callState = new CallState(new Guid((string)args.ContinuationData[WabArgName.CorrelationId]), false); this.authorizationResult = this.webUi.ProcessAuthorizationResult(args, callState); }
public async Task<AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState) { bool ssoMode = ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri); if (this.promptBehavior == PromptBehavior.Never && !ssoMode && redirectUri.Scheme != Constant.MsAppScheme) { throw new ArgumentException(AdalErrorMessageEx.RedirectUriUnsupportedWithPromptBehaviorNever, "redirectUri"); } WebAuthenticationResult webAuthenticationResult; WebAuthenticationOptions options = (this.useCorporateNetwork && (ssoMode || redirectUri.Scheme == Constant.MsAppScheme)) ? WebAuthenticationOptions.UseCorporateNetwork : WebAuthenticationOptions.None; if (this.promptBehavior == PromptBehavior.Never) { options |= WebAuthenticationOptions.SilentMode; } try { if (ssoMode) { webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri); } else { webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri, redirectUri); } } catch (FileNotFoundException ex) { throw new AdalException(AdalError.AuthenticationUiFailed, ex); } catch (Exception ex) { if (this.promptBehavior == PromptBehavior.Never) { throw new AdalException(AdalError.UserInteractionRequired, ex); } throw new AdalException(AdalError.AuthenticationUiFailed, ex); } AuthorizationResult result = ProcessAuthorizationResult(webAuthenticationResult, callState); return result; }
public void Authenticate(Uri authorizationUri, Uri redirectUri, IDictionary<string, object> headersMap, CallState callState) { ValueSet set = new ValueSet(); foreach (string key in headersMap.Keys) { set[key] = headersMap[key]; } try { WebAuthenticationBroker.AuthenticateAndContinue(authorizationUri, ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri) ? null : redirectUri, set, WebAuthenticationOptions.None); } catch (Exception ex) { throw new AdalException(AdalError.AuthenticationUiFailed, ex); } }
public void EndClientMetricsRecord(string endpoint, CallState callState) { if (callState != null && callState.AuthorityType == AuthorityType.AAD && metricsTimer != null) { metricsTimer.Stop(); lastResponseTime = metricsTimer.ElapsedMilliseconds; lastCorrelationId = callState.CorrelationId; lastEndpoint = endpoint; lock (PendingClientMetricsLock) { if (pendingClientMetrics == null) { pendingClientMetrics = this; } } } }
internal static WsTrustAddress ExtractWsTrustAddressFromMex(XDocument mexDocument, UserAuthType userAuthType, CallState callState) { WsTrustAddress address = null; MexPolicy policy = null; try { Dictionary <string, MexPolicy> policies = ReadPolicies(mexDocument); Dictionary <string, MexPolicy> bindings = ReadPolicyBindings(mexDocument, policies); SetPolicyEndpointAddresses(mexDocument, bindings); Random random = new Random(); //try ws-trust 1.3 first policy = policies.Values.Where( p => p.Url != null && p.AuthType == userAuthType && p.Version == WsTrustVersion.WsTrust13) .OrderBy(p => random.Next()) .FirstOrDefault() ?? policies.Values.Where(p => p.Url != null && p.AuthType == userAuthType) .OrderBy(p => random.Next()) .FirstOrDefault(); if (policy != null) { address = new WsTrustAddress(); address.Uri = policy.Url; address.Version = policy.Version; } else if (userAuthType == UserAuthType.IntegratedAuth) { throw new AdalException(AdalError.IntegratedAuthFailed, new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument)); } else { throw new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument); } } catch (XmlException ex) { throw new AdalException(AdalError.ParsingWsMetadataExchangeFailed, ex); } return(address); }
/// <summary> /// Parse a delimited string of key-value pairs in to a dictionary. /// </summary> /// <param name="input">Delimited string of key-value pairs</param> /// <param name="delimiter">Character used as a delimiter between key-value pairs</param> /// <param name="urlDecode">True to perform URL decoding of both the keys and values</param> /// <param name="lowercaseKeys">True to make all resulting keys lower-case</param> /// <param name="strict">Throw <see cref="ArgumentException"/> when the input string contains a malformed key-value pair</param> /// <exception cref="ArgumentException">Thrown if <paramref name="strict"/> is true and a malformed key-value pair is present in <paramref name="input"/></exception> /// <returns>Dictionary of string key-value pairs</returns> private static Dictionary <string, string> ParseKeyValueList(string input, char delimiter, bool urlDecode, bool lowercaseKeys, CallState callState, bool strict) { var response = new Dictionary <string, string>(); List <string> queryPairs = SplitWithQuotes(input, delimiter); foreach (string queryPair in queryPairs) { List <string> pair = SplitWithQuotes(queryPair, '='); if (pair.Count == 2 && !string.IsNullOrWhiteSpace(pair[0]) && !string.IsNullOrWhiteSpace(pair[1])) { string key = pair[0]; string value = pair[1]; // Url decoding is needed for parsing OAuth response, but not for parsing WWW-Authenticate header in 401 challenge if (urlDecode) { key = UrlDecode(key); value = UrlDecode(value); } if (lowercaseKeys) { key = key.Trim().ToLowerInvariant(); } value = value.Trim().Trim(new[] { '\"' }).Trim(); if (response.ContainsKey(key) && callState != null) { PlatformPlugin.Logger.Warning(callState, string.Format(CultureInfo.CurrentCulture, "Key/value pair list contains redundant key '{0}'.", key)); } response[key] = value; } else if (strict && pair.Count > 2) { throw new ArgumentException(nameof(input)); } } return(response); }
public async Task <IHttpWebResponse> GetResponseSyncOrAsync(CallState callState) { if (this.BodyParameters != null) { using (Stream stream = await GetRequestStreamSyncOrAsync(callState)) { this.BodyParameters.WriteToStream(stream); } } #if ADAL_NET if (callState != null && callState.CallSync) { return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(this.request.GetResponse())); } #endif return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(await this.request.GetResponseAsync())); }
// This constructor is called by ContinueAcquireTokenAsync after WAB call has returned. public AcquireTokenInteractiveHandler(Authenticator authenticator, TokenCache tokenCache, IWebAuthenticationBrokerContinuationEventArgs args) : this( authenticator, tokenCache, (string)args.ContinuationData[WabArgName.Resource], (string)args.ContinuationData[WabArgName.ClientId], new Uri((string)args.ContinuationData[WabArgName.RedirectUri]), PromptBehavior.Always, // This is simply to disable cache lookup. In fact, there is no authorize call at this point and promptBehavior is not applicable. new UserIdentifier((string)args.ContinuationData[WabArgName.UserId], (UserIdentifierType)((int)args.ContinuationData[WabArgName.UserIdType])), null, NetworkPlugin.WebUIFactory.Create(), false) { CallState callState = new CallState(new Guid((string)args.ContinuationData[WabArgName.CorrelationId]), false); this.authorizationResult = this.webUi.ProcessAuthorizationResult(args, callState); }
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); }
public AcquireTokenInteractiveHandler(Authenticator authenticator, TokenCache tokenCache, AuthenticationContextDelegate authenticationContextDelegate, IWebAuthenticationBrokerContinuationEventArgs args) : this( authenticator, tokenCache, (string)args.ContinuationData[WabArgName.Resource], (string)args.ContinuationData[WabArgName.ClientId], new Uri((string)args.ContinuationData[WabArgName.RedirectUri]), PromptBehavior.RefreshSession, new UserIdentifier((string)args.ContinuationData[WabArgName.UserId], (UserIdentifierType)((int)args.ContinuationData[WabArgName.UserIdType])), null, NetworkPlugin.WebUIFactory.Create(), false) { CallState callState = new CallState(new Guid((string)args.ContinuationData[WabArgName.CorrelationId]), false); this.authorizationResult = this.webUi.ProcessAuthorizationResult(args, callState); this.authenticationContextDelegate = authenticationContextDelegate; }
public async Task UpdateFromTemplateAsync(CallState callState) { if (!this.updatedFromTemplate) { var authorityUri = new Uri(this.Authority); string host = authorityUri.Authority; string path = authorityUri.AbsolutePath.Substring(1); string tenant = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal)); AuthenticatorTemplate matchingTemplate = await AuthenticatorTemplateList.FindMatchingItemAsync(this.ValidateAuthority, host, tenant, callState); this.AuthorizationUri = matchingTemplate.AuthorizeEndpoint.Replace("{tenant}", tenant); this.TokenUri = matchingTemplate.TokenEndpoint.Replace("{tenant}", tenant); this.UserRealmUri = CanonicalizeUri(matchingTemplate.UserRealmEndpoint); this.IsTenantless = (string.Compare(tenant, TenantlessTenantName, StringComparison.OrdinalIgnoreCase) == 0); this.SelfSignedJwtAudience = matchingTemplate.Issuer.Replace("{tenant}", tenant); this.updatedFromTemplate = true; } }
public static async Task<WsTrustResponse> SendRequestAsync(Uri url, UserCredential credential, CallState callState) { IHttpClient request = PlatformPlugin.HttpClientFactory.Create(url.AbsoluteUri, callState); request.ContentType = "application/soap+xml"; if (credential.UserAuthType == UserAuthType.IntegratedAuth) { SetKerberosOption(request); } StringBuilder messageBuilder = BuildMessage(DefaultAppliesTo, url.AbsoluteUri, credential); request.Headers["SOAPAction"] = XmlNamespace.Issue.ToString(); WsTrustResponse wstResponse; try { request.BodyParameters = new StringRequestParameters(messageBuilder); IHttpWebResponse response = await request.GetResponseAsync(); wstResponse = WsTrustResponse.CreateFromResponse(response.ResponseStream); } catch (HttpRequestWrapperException ex) { string errorMessage; try { XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.WebResponse.ResponseStream); errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState); } catch (AdalException) { errorMessage = "See inner exception for detail."; } throw new AdalServiceException( AdalError.FederatedServiceReturnedError, string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, url, errorMessage), null, ex); } return wstResponse; }
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 static AuthorizationResult ProcessAuthorizationResult(WebAuthenticationResult webAuthenticationResult, CallState callState) { AuthorizationResult result; switch (webAuthenticationResult.ResponseStatus) { case WebAuthenticationStatus.Success: result = OAuth2Response.ParseAuthorizeResponse(webAuthenticationResult.ResponseData, callState); break; case WebAuthenticationStatus.ErrorHttp: result = new AuthorizationResult(AdalError.AuthenticationFailed, webAuthenticationResult.ResponseErrorDetail.ToString()); break; case WebAuthenticationStatus.UserCancel: result = new AuthorizationResult(AdalError.AuthenticationCanceled, AdalErrorMessage.AuthenticationCanceled); break; default: result = new AuthorizationResult(AdalError.AuthenticationFailed, AdalErrorMessage.AuthorizationServerInvalidResponse); break; } return result; }
public async Task<AuthorizationResult> AuthenticateAsync(Uri authorizationUri, Uri redirectUri, CallState callState) { string key = authorizationUri.AbsoluteUri + redirectUri.AbsoluteUri; if (IOMap.ContainsKey(key)) { string value = IOMap[key]; if (value[0] == 'P') { return OAuth2Response.ParseAuthorizeResponse(value.Substring(1), callState); } if (value[0] == 'A') { string []segments = value.Substring(1).Split(new [] { Delimiter }, StringSplitOptions.RemoveEmptyEntries); return new AuthorizationResult(error: segments[0], errorDescription: segments[1]); } } return null; }
public static string ReadErrorResponse(XDocument responseDocument, CallState callState) { string errorMessage = null; try { XElement body = responseDocument.Descendants(XmlNamespace.SoapEnvelope + "Body").FirstOrDefault(); if (body != null) { XElement fault = body.Elements(XmlNamespace.SoapEnvelope + "Fault").FirstOrDefault(); if (fault != null) { XElement reason = fault.Elements(XmlNamespace.SoapEnvelope + "Reason").FirstOrDefault(); if (reason != null) { XElement text = reason.Elements(XmlNamespace.SoapEnvelope + "Text").FirstOrDefault(); if (text != null) { using (var reader = text.CreateReader()) { reader.MoveToContent(); errorMessage = reader.ReadInnerXml(); } } } } } } catch (XmlException ex) { var adalEx = new AdalException(AdalError.ParsingWsTrustResponseFailed, ex); PlatformPlugin.Logger.LogException(callState, adalEx); throw adalEx; } return(errorMessage); }
public override async Task <bool> IsUserLocalAsync(CallState callState) { if (!UserInformation.NameAccessAllowed) { // The access is not allowed and we cannot determine whether this is a local user or not. So, we do NOT add form auth parameter. // This is the case where we can advise customers to add extra query parameter if they want. PlatformPlugin.Logger.Information(callState, "Cannot access user information to determine whether it is a local user or not due to machine's privacy setting."); return(false); } try { return(string.IsNullOrEmpty(await UserInformation.GetDomainNameAsync())); } catch (UnauthorizedAccessException) { PlatformPlugin.Logger.Information(callState, "Cannot try Windows Integrated Auth due to lack of Enterprise capability."); // This mostly means Enterprise capability is missing, so WIA cannot be used and // we return true to add form auth parameter in the caller. return(true); } }
public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState) { try { this.parameters.CallerViewController.InvokeOnMainThread(() => { var navigationController = new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri, redirectUri.OriginalString, CallbackMethod, this.parameters.PreferredStatusBarStyle); navigationController.ModalPresentationStyle = this.parameters.ModalPresentationStyle; navigationController.ModalTransitionStyle = this.parameters.ModalTransitionStyle; navigationController.TransitioningDelegate = this.parameters.TransitioningDelegate; this.parameters.CallerViewController.PresentViewController(navigationController, true, null); }); } catch (Exception ex) { this.parameters = null; throw new AdalException(AdalError.AuthenticationUiFailed, ex); } }
public static string ReadErrorResponse(XDocument responseDocument, CallState callState) { string errorMessage = null; try { XElement body = responseDocument.Descendants(XmlNamespace.SoapEnvelope + "Body").FirstOrDefault(); if (body != null) { XElement fault = body.Elements(XmlNamespace.SoapEnvelope + "Fault").FirstOrDefault(); if (fault != null) { errorMessage = GetFaultMessage(fault); } } } catch (XmlException ex) { throw new AdalException(AdalError.ParsingWsTrustResponseFailed, ex); } return(errorMessage); }
public async Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState) { bool ssoMode = ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri); if (this.promptBehavior == PromptBehavior.Never && !ssoMode && redirectUri.Scheme != Constant.MsAppScheme) { throw new ArgumentException(AdalErrorMessageEx.RedirectUriUnsupportedWithPromptBehaviorNever, "redirectUri"); } WebAuthenticationResult webAuthenticationResult; WebAuthenticationOptions options = (this.useCorporateNetwork && (ssoMode || redirectUri.Scheme == Constant.MsAppScheme)) ? WebAuthenticationOptions.UseCorporateNetwork : WebAuthenticationOptions.None; if (this.promptBehavior == PromptBehavior.Never) { options |= WebAuthenticationOptions.SilentMode; } try { if (ssoMode) { webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri); } else { webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri, redirectUri); } } catch (FileNotFoundException ex) { throw new AdalException(AdalError.AuthenticationUiFailed, ex); } catch (Exception ex) { if (this.promptBehavior == PromptBehavior.Never) { throw new AdalException(AdalError.UserInteractionRequired, ex); } throw new AdalException(AdalError.AuthenticationUiFailed, ex); } AuthorizationResult result = ProcessAuthorizationResult(webAuthenticationResult, callState); return(result); }
public async Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState) { returnedUriReady = new SemaphoreSlim(0); Authenticate(authorizationUri, redirectUri, callState); await returnedUriReady.WaitAsync(); return(authorizationResult); }
private static void Warning(CallState callState, string callerFilePath, string format, params object[] args) { AdalEventSource.Warning(PrepareLogMessage(callState, GetCallerFilename(callerFilePath), format, args)); }
internal void StoreToCache(AuthenticationResultEx result, string authority, string resource, string clientId, TokenSubjectType subjectType, CallState callState) { lock (cacheLock) { PlatformPlugin.Logger.Verbose(callState, "Storing token in the cache..."); string uniqueId = (result.Result.UserInfo != null) ? result.Result.UserInfo.UniqueId : null; string displayableId = (result.Result.UserInfo != null) ? result.Result.UserInfo.DisplayableId : null; this.OnBeforeWrite(new TokenCacheNotificationArgs { Resource = resource, ClientId = clientId, UniqueId = uniqueId, DisplayableId = displayableId }); TokenCacheKey tokenCacheKey = new TokenCacheKey(authority, resource, clientId, subjectType, result.Result.UserInfo); this.tokenCacheDictionary[tokenCacheKey] = result; PlatformPlugin.Logger.Verbose(callState, "An item was stored in the cache"); this.UpdateCachedMrrtRefreshTokens(result, clientId, subjectType); this.HasStateChanged = true; } }
internal static async Task <UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState) { string userRealmEndpoint = userRealmUri; userRealmEndpoint += (userName + "?api-version=1.0"); PlatformPlugin.Logger.Information(callState, string.Format(CultureInfo.CurrentCulture, " Sending user realm discovery request to '{0}'", userRealmEndpoint)); var client = new AdalHttpClient(userRealmEndpoint, callState) { Client = { Accept = "application/json" } }; return(await client.GetResponseAsync <UserRealmDiscoveryResponse>(ClientMetricsEndpointType.UserRealmDiscovery)); }
public static async Task <WsTrustResponse> SendRequestAsync(Uri url, UserCredential credential, CallState callState) { IHttpWebRequest request = PlatformPlugin.HttpWebRequestFactory.Create(url.AbsoluteUri); request.ContentType = "application/soap+xml; charset=utf-8"; if (credential.UserAuthType == UserAuthType.IntegratedAuth) { SetKerberosOption(request); } StringBuilder messageBuilder = BuildMessage(DefaultAppliesTo, url.AbsoluteUri, credential); Dictionary <string, string> headers = new Dictionary <string, string> { { "SOAPAction", XmlNamespace.Issue.ToString() } }; WsTrustResponse wstResponse; try { HttpHelper.SetPostRequest(request, new RequestParameters(messageBuilder), callState, headers); IHttpWebResponse response = await request.GetResponseSyncOrAsync(callState); wstResponse = WsTrustResponse.CreateFromResponse(response.GetResponseStream()); } catch (WebException ex) { string errorMessage; try { XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.Response.GetResponseStream()); errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState); } catch (AdalException) { errorMessage = "See inner exception for detail."; } throw new AdalServiceException( AdalError.FederatedServiceReturnedError, string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, url, errorMessage), ex); } return(wstResponse); }
private static AuthorizationResult ProcessAuthorizationResult(WebAuthenticationResult webAuthenticationResult, CallState callState) { AuthorizationResult result; switch (webAuthenticationResult.ResponseStatus) { case WebAuthenticationStatus.Success: result = new AuthorizationResult(AuthorizationStatus.Success, webAuthenticationResult.ResponseData); break; case WebAuthenticationStatus.ErrorHttp: result = new AuthorizationResult(AuthorizationStatus.ErrorHttp, webAuthenticationResult.ResponseErrorDetail.ToString(CultureInfo.CurrentCulture)); break; case WebAuthenticationStatus.UserCancel: result = new AuthorizationResult(AuthorizationStatus.UserCancel, null); break; default: result = new AuthorizationResult(AuthorizationStatus.UnknownError, null); break; } return(result); }
internal AuthenticationResultEx LoadFromCache(CacheQueryData cacheQueryData, CallState callState) { lock (cacheLock) { PlatformPlugin.Logger.Verbose(callState, "Looking up cache for a token..."); AuthenticationResultEx resultEx = null; KeyValuePair <TokenCacheKey, AuthenticationResultEx>?kvp = this.LoadSingleItemFromCache(cacheQueryData, callState); if (kvp.HasValue) { TokenCacheKey cacheKey = kvp.Value.Key; resultEx = kvp.Value.Value.Clone(); bool tokenNearExpiry = (resultEx.Result.ExpiresOn <= DateTime.UtcNow + TimeSpan.FromMinutes(ExpirationMarginInMinutes)); bool tokenExtendedLifeTimeExpired = (resultEx.Result.ExtendedExpiresOn <= DateTime.UtcNow); //check for cross-tenant authority if (!cacheKey.Authority.Equals(cacheQueryData.Authority)) { // this is a cross-tenant result. use RT only resultEx.Result.AccessToken = null; PlatformPlugin.Logger.Information(callState, "Cross Tenant refresh token was found in the cache"); } else if (tokenNearExpiry && !cacheQueryData.ExtendedLifeTimeEnabled) { resultEx.Result.AccessToken = null; PlatformPlugin.Logger.Information(callState, "An expired or near expiry token was found in the cache"); } else if (!cacheKey.ResourceEquals(cacheQueryData.Resource)) { PlatformPlugin.Logger.Information(callState, string.Format(CultureInfo.CurrentCulture, "Multi resource refresh token for resource '{0}' will be used to acquire token for '{1}'", cacheKey.Resource, cacheQueryData.Resource)); var newResultEx = new AuthenticationResultEx { Result = new AuthenticationResult(null, null, DateTimeOffset.MinValue), RefreshToken = resultEx.RefreshToken, ResourceInResponse = resultEx.ResourceInResponse }; newResultEx.Result.UpdateTenantAndUserInfo(resultEx.Result.TenantId, resultEx.Result.IdToken, resultEx.Result.UserInfo); resultEx = newResultEx; } else if (!tokenExtendedLifeTimeExpired && cacheQueryData.ExtendedLifeTimeEnabled && tokenNearExpiry) { resultEx.Result.ExtendedLifeTimeToken = true; resultEx.Result.ExpiresOn = resultEx.Result.ExtendedExpiresOn; PlatformPlugin.Logger.Information(callState, "The extendedLifeTime is enabled and a stale AT with extendedLifeTimeEnabled is returned."); } else if (tokenExtendedLifeTimeExpired) { resultEx.Result.AccessToken = null; PlatformPlugin.Logger.Information(callState, "The AT has expired its ExtendedLifeTime"); } else { PlatformPlugin.Logger.Information(callState, string.Format(CultureInfo.CurrentCulture, "{0} minutes left until token in cache expires", (resultEx.Result.ExpiresOn - DateTime.UtcNow).TotalMinutes)); } if (resultEx.Result.AccessToken == null && resultEx.RefreshToken == null) { this.tokenCacheDictionary.Remove(cacheKey); PlatformPlugin.Logger.Information(callState, "An old item was removed from the cache"); this.HasStateChanged = true; resultEx = null; } if (resultEx != null) { PlatformPlugin.Logger.Information(callState, "A matching item (access token or refresh token or both) was found in the cache"); } } else { PlatformPlugin.Logger.Information(callState, "No matching token was found in the cache"); } return(resultEx); } }
public async Task VerifyAnotherHostByInstanceDiscoveryAsync(string host, string tenant, CallState callState) { string instanceDiscoveryEndpoint = this.InstanceDiscoveryEndpoint; instanceDiscoveryEndpoint += ("?api-version=1.0&authorization_endpoint=" + AuthorizeEndpointTemplate); instanceDiscoveryEndpoint = instanceDiscoveryEndpoint.Replace("{host}", host); instanceDiscoveryEndpoint = instanceDiscoveryEndpoint.Replace("{tenant}", tenant); try { var client = new AdalHttpClient(instanceDiscoveryEndpoint, callState); InstanceDiscoveryResponse discoveryResponse = await client.GetResponseAsync <InstanceDiscoveryResponse>().ConfigureAwait(false); if (discoveryResponse.TenantDiscoveryEndpoint == null) { throw new AdalException(AdalError.AuthorityNotInValidList); } } catch (AdalServiceException ex) { throw new AdalException((ex.ErrorCode == "invalid_instance") ? AdalError.AuthorityNotInValidList : AdalError.AuthorityValidationFailed, ex); } }
private KeyValuePair <TokenCacheKey, AuthenticationResultEx>?LoadSingleItemFromCache(CacheQueryData cacheQueryData, CallState callState) { lock (cacheLock) { // First identify all potential tokens. List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > items = this.QueryCache(cacheQueryData.Authority, cacheQueryData.ClientId, cacheQueryData.SubjectType, cacheQueryData.UniqueId, cacheQueryData.DisplayableId, cacheQueryData.AssertionHash); List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > resourceSpecificItems = items.Where(p => p.Key.ResourceEquals(cacheQueryData.Resource)).ToList(); int resourceValuesCount = resourceSpecificItems.Count(); KeyValuePair <TokenCacheKey, AuthenticationResultEx>?returnValue = null; switch (resourceValuesCount) { case 1: PlatformPlugin.Logger.Information(callState, "An item matching the requested resource was found in the cache"); returnValue = resourceSpecificItems.First(); break; case 0: { // There are no resource specific tokens. Choose any of the MRRT tokens if there are any. List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > mrrtItems = items.Where(p => p.Value.IsMultipleResourceRefreshToken).ToList(); if (mrrtItems.Any()) { returnValue = mrrtItems.First(); PlatformPlugin.Logger.Information(callState, "A Multi Resource Refresh Token for a different resource was found which can be used"); } } break; default: throw new AdalException(AdalError.MultipleTokensMatched); } // check for tokens issued to same client_id/user_id combination, but any tenant. // this check only applies to user tokens. client tokens should be ignored. if (returnValue == null && cacheQueryData.SubjectType != TokenSubjectType.Client) { List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > itemsForAllTenants = this.QueryCache( null, cacheQueryData.ClientId, cacheQueryData.SubjectType, cacheQueryData.UniqueId, cacheQueryData.DisplayableId, cacheQueryData.AssertionHash); if (itemsForAllTenants.Count != 0) { returnValue = itemsForAllTenants.First(); } // check if the token was issued by AAD if (returnValue != null && Authenticator.DetectAuthorityType(returnValue.Value.Key.Authority) == AuthorityType.ADFS) { returnValue = null; } } return(returnValue); } }
internal static void Error(CallState callState, Exception ex, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "") { AdalEventSource.Error(PrepareLogMessage(callState, GetCallerFilename(callerFilePath), "{0}", ex)); }