public override void ViewDidLoad() { base.ViewDidLoad(); View.BackgroundColor = UIColor.White; webView = new UIWebView((CGRect)View.Bounds); webView.ShouldStartLoad = (wView, request, navType) => { if (request == null) { return(true); } string requestUrlString = request.Url.ToString(); if (requestUrlString.StartsWith(BrokerConstants.BrowserExtPrefix, StringComparison.OrdinalIgnoreCase)) { DispatchQueue.MainQueue.DispatchAsync(() => CancelAuthentication(null, null)); requestUrlString = requestUrlString.Replace(BrokerConstants.BrowserExtPrefix, "https://"); DispatchQueue.MainQueue.DispatchAsync( () => UIApplication.SharedApplication.OpenUrl(new NSUrl(requestUrlString))); this.DismissViewController(true, null); return(false); } if (requestUrlString.ToLower(CultureInfo.InvariantCulture).StartsWith(callback.ToLower(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase) || requestUrlString.StartsWith(BrokerConstants.BrowserExtInstallPrefix, StringComparison.OrdinalIgnoreCase)) { callbackMethod(new AuthorizationResult(AuthorizationStatus.Success, request.Url.ToString())); this.DismissViewController(true, null); return(false); } if (requestUrlString.StartsWith(BrokerConstants.DeviceAuthChallengeRedirect, StringComparison.CurrentCultureIgnoreCase)) { Uri uri = new Uri(requestUrlString); string query = uri.Query; if (query.StartsWith("?", StringComparison.OrdinalIgnoreCase)) { query = query.Substring(1); } Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null); string responseHeader = PlatformPlugin.DeviceAuthHelper.CreateDeviceAuthChallengeResponse(keyPair).Result; NSMutableUrlRequest newRequest = (NSMutableUrlRequest)request.MutableCopy(); newRequest.Url = new NSUrl(keyPair["SubmitUrl"]); newRequest[BrokerConstants.ChallengeResponseHeader] = responseHeader; wView.LoadRequest(newRequest); return(false); } if (!request.Url.AbsoluteString.Equals("about:blank", StringComparison.CurrentCultureIgnoreCase) && !request.Url.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase)) { AuthorizationResult result = new AuthorizationResult(AuthorizationStatus.ErrorHttp); result.Error = AdalError.NonHttpsRedirectNotSupported; result.ErrorDescription = AdalErrorMessage.NonHttpsRedirectNotSupported; callbackMethod(result); this.DismissViewController(true, null); return(false); } return(true); }; webView.LoadFinished += delegate { // If the title is too long, iOS automatically truncates it and adds ... this.Title = webView.EvaluateJavascript(@"document.title") ?? "Sign in"; }; View.AddSubview(webView); this.NavigationItem.LeftBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Cancel, this.CancelAuthentication); webView.LoadRequest(new NSUrlRequest(new NSUrl(this.url))); // if this is false, page will be 'zoomed in' to normal size //webView.ScalesPageToFit = true; }
public override string ToString() { StringBuilder messageBuilder = new StringBuilder(); foreach (KeyValuePair <string, string> kvp in this) { EncodingHelper.AddKeyValueString(messageBuilder, EncodingHelper.UrlEncode(kvp.Key), EncodingHelper.UrlEncode(kvp.Value)); } if (this.ExtraQueryParameter != null) { messageBuilder.Append('&' + this.ExtraQueryParameter); } return(messageBuilder.ToString()); }
public void AcquireToken(IDictionary <string, string> brokerPayload) { if (brokerPayload.ContainsKey("broker_install_url")) { string url = brokerPayload["broker_install_url"]; Uri uri = new Uri(url); string query = uri.Query; if (query.StartsWith("?")) { query = query.Substring(1); } Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null); PlatformParameters pp = PlatformParameters as PlatformParameters; pp.CallerActivity.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(keyPair["app_link"]))); throw new AdalException(AdalErrorAndroidEx.BrokerApplicationRequired, AdalErrorMessageAndroidEx.BrokerApplicationRequired); } Context mContext = Application.Context; AuthenticationRequest request = new AuthenticationRequest(brokerPayload); PlatformParameters platformParams = PlatformParameters as PlatformParameters; // BROKER flow intercepts here // cache and refresh call happens through the authenticator service if (mBrokerProxy.VerifyUser(request.LoginHint, request.UserId)) { CallState.Logger.Verbose(null, "It switched to broker for context: " + mContext.PackageName); request.BrokerAccountName = request.LoginHint; // Don't send background request, if prompt flag is always or // refresh_session bool hasAccountNameOrUserId = !string.IsNullOrEmpty(request.BrokerAccountName) || !string.IsNullOrEmpty(request.UserId); if (string.IsNullOrEmpty(request.Claims) && hasAccountNameOrUserId) { CallState.Logger.Verbose(null, "User is specified for background token request"); resultEx = mBrokerProxy.GetAuthTokenInBackground(request, platformParams.CallerActivity); } else { CallState.Logger.Verbose(null, "User is not specified for background token request"); } if (resultEx != null && resultEx.Result != null && !string.IsNullOrEmpty(resultEx.Result.AccessToken)) { CallState.Logger.Verbose(null, "Token is returned from background call "); readyForResponse.Release(); return; } // Launch broker activity // if cache and refresh request is not handled. // Initial request to authenticator needs to launch activity to // record calling uid for the account. This happens for Prompt auto // or always behavior. CallState.Logger.Verbose(null, "Token is not returned from backgroud call"); // Only happens with callback since silent call does not show UI CallState.Logger.Verbose(null, "Launch activity for Authenticator"); CallState.Logger.Verbose(null, "Starting Authentication Activity"); if (resultEx == null) { CallState.Logger.Verbose(null, "Initial request to authenticator"); // Log the initial request but not force a prompt } if (brokerPayload.ContainsKey("silent_broker_flow")) { throw new AdalSilentTokenAcquisitionException(); } // onActivityResult will receive the response // Activity needs to launch to record calling app for this // account Intent brokerIntent = mBrokerProxy.GetIntentForBrokerActivity(request, platformParams.CallerActivity); if (brokerIntent != null) { try { CallState.Logger.Verbose(null, "Calling activity pid:" + Android.OS.Process.MyPid() + " tid:" + Android.OS.Process.MyTid() + "uid:" + Android.OS.Process.MyUid()); platformParams.CallerActivity.StartActivityForResult(brokerIntent, 1001); } catch (ActivityNotFoundException e) { CallState.Logger.Error(null, e); } } } else { throw new AdalException(AdalErrorAndroidEx.NoBrokerAccountFound, "Add requested account as a Workplace account via Settings->Accounts or set UseBroker=true."); } }
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 (ex.WebResponse.StatusCode == HttpStatusCode.BadRequest && tokenResponse.Error == AdalError.InteractionRequired) { throw new AdalClaimChallengeException(tokenResponse.Error, tokenResponse.ErrorDescription, tokenResponse.Claims); } 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); }
private StringBuilder ToStringBuilder() { StringBuilder messageBuilder = new StringBuilder(); if (this.stringBuilderParameter != null) { messageBuilder.Append(this.stringBuilderParameter); } foreach (KeyValuePair <string, string> kvp in this) { EncodingHelper.AddKeyValueString(messageBuilder, EncodingHelper.UrlEncode(kvp.Key), EncodingHelper.UrlEncode(kvp.Value)); } this.AddSecureParametersToMessageBuilder(messageBuilder); if (this.ExtraQueryParameter != null) { messageBuilder.Append('&' + this.ExtraQueryParameter); } return(messageBuilder); }