diff options
Diffstat (limited to 'src')
5 files changed, 68 insertions, 56 deletions
diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs index eec7d1c..4740b4b 100644 --- a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs @@ -1542,18 +1542,14 @@ namespace DotNetOpenAuth.Messaging { || response.StatusCode == HttpStatusCode.RedirectMethod || response.StatusCode == HttpStatusCode.TemporaryRedirect, "response", "Redirecting response expected."); - Requires.Argument(response.Headers.Location != null, "response", "Redirect URL header expected."); - Requires.Argument(response.Content == null || response.Content is FormUrlEncodedContent, "response", "FormUrlEncodedContent expected"); - var builder = new UriBuilder(response.Headers.Location); - if (response.Content != null) { - var content = response.Content.ReadAsStringAsync(); - Assumes.True(content.IsCompleted); // cached in memory, so it should never complete asynchronously. - var formFields = HttpUtility.ParseQueryString(content.Result).ToDictionary(); - MessagingUtilities.AppendQueryArgs(builder, formFields); + if (response.Headers.Location != null) { + return response.Headers.Location; + } else { + // Some responses are so large that they're HTML/JS self-posting pages. + // We can't create long URLs for those, at present. + throw new NotSupportedException(); } - - return builder.Uri; } /// <summary> diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs index 5900e7b..4c988a8 100644 --- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs @@ -740,10 +740,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { // If an Identifier is preset on this control, preload discovery on that identifier, // but only if we're not already persisting an authentication result since that would // be redundant. - var response = Task.Run(() => this.GetAuthenticationResponseAsync(CancellationToken.None)).GetAwaiter().GetResult(); - if (this.Identifier != null && response == null) { - this.PreloadDiscoveryAsync(this.Identifier, CancellationToken.None).Wait(); - } + this.Page.RegisterAsyncTask(new PageAsyncTask(async ct => { + var response = await this.GetAuthenticationResponseAsync(ct); + if (this.Identifier != null && response == null) { + await this.PreloadDiscoveryAsync(this.Identifier, ct); + } + })); } /// <summary> diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs index ae962ed..958c721 100644 --- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs @@ -12,6 +12,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System.Drawing.Design; using System.Globalization; using System.Linq; + using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -57,6 +58,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { #endregion + private HttpResponseMessage authenticationRequestRedirect; + /// <summary> /// Initializes a new instance of the <see cref="OpenIdButton"/> class. /// </summary> @@ -119,17 +122,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param> protected override void RaisePostBackEvent(string eventArgument) { if (!this.PrecreateRequest) { - try { - // We have to use Task.Run here to escape our SynchronizationContext - Task.Run( - async delegate { - var requests = await this.CreateRequestsAsync(CancellationToken.None); - var request = requests.First(); - await request.RedirectToProviderAsync(new HttpContextWrapper(this.Context)); - }).GetAwaiter().GetResult(); - } catch (InvalidOperationException ex) { - throw ErrorUtilities.Wrap(ex, OpenIdStrings.OpenIdEndpointNotFound); - } + this.Page.RegisterAsyncTask(new PageAsyncTask(async ct => { + try { + var requests = await this.CreateRequestsAsync(ct); + var request = requests.First(); + await request.RedirectToProviderAsync(new HttpContextWrapper(this.Context), ct); + } catch (InvalidOperationException ex) { + throw ErrorUtilities.Wrap(ex, OpenIdStrings.OpenIdEndpointNotFound); + } + })); } } @@ -142,6 +143,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { if (!this.DesignMode) { ErrorUtilities.VerifyOperation(this.Identifier != null, OpenIdStrings.NoIdentifierSet); + + if (this.PrecreateRequest) { + this.Page.RegisterAsyncTask( + new PageAsyncTask( + async ct => { + var requests = await this.CreateRequestsAsync(ct); + this.authenticationRequestRedirect = await requests.FirstOrDefault().GetRedirectingResponseAsync(ct); + })); + } } } @@ -156,9 +166,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } else { string tooltip = this.Text; if (this.PrecreateRequest && !this.DesignMode) { - IAuthenticationRequest request = Task.Run(() => this.CreateRequestsAsync(CancellationToken.None)).GetAwaiter().GetResult().FirstOrDefault(); - if (request != null) { - this.RenderOpenIdMessageTransmissionAsAnchorAttributesAsync(writer, request, tooltip, CancellationToken.None).Wait(); + if (this.authenticationRequestRedirect != null) { + this.RenderOpenIdMessageTransmissionAsAnchorAttributes(writer, this.authenticationRequestRedirect, tooltip); } else { tooltip = OpenIdStrings.OpenIdEndpointNotFound; } diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs index 0d5435d..2a14ae3 100644 --- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs @@ -289,11 +289,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { this.Identifier = userSuppliedIdentifier; - var serializer = new JavaScriptSerializer(); - this.discoveryResult = Task.Run(async delegate { - IEnumerable<IAuthenticationRequest> requests = await this.CreateRequestsAsync(this.Identifier, CancellationToken.None); - return serializer.Serialize(await this.AjaxRelyingParty.AsJsonDiscoveryResultAsync(requests, CancellationToken.None)); - }).GetAwaiter().GetResult(); + this.Page.RegisterAsyncTask(new PageAsyncTask(async ct => { + var serializer = new JavaScriptSerializer(); + IEnumerable<IAuthenticationRequest> requests = await this.CreateRequestsAsync(this.Identifier, ct); + this.discoveryResult = serializer.Serialize(await this.AjaxRelyingParty.AsJsonDiscoveryResultAsync(requests, ct)); + })); } /// <summary> @@ -346,16 +346,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { // but our AJAX controls hide an old OpenID message in a postback payload, // so we deserialize it and process it when appropriate. if (this.Page.IsPostBack) { - var response = Task.Run(() => this.GetAuthenticationResponseAsync(CancellationToken.None)).GetAwaiter().GetResult(); - if (response != null && !this.AuthenticationProcessedAlready) { - // Only process messages targeted at this control. - // Note that Stateless mode causes no receiver to be indicated. - string receiver = response.GetUntrustedCallbackArgument(ReturnToReceivingControlId); - if (receiver == null || receiver == this.ClientID) { - this.ProcessResponse(response); - this.AuthenticationProcessedAlready = true; + this.Page.RegisterAsyncTask(new PageAsyncTask(async ct => { + var response = await this.GetAuthenticationResponseAsync(ct); + if (response != null && !this.AuthenticationProcessedAlready) { + // Only process messages targeted at this control. + // Note that Stateless mode causes no receiver to be indicated. + string receiver = response.GetUntrustedCallbackArgument(ReturnToReceivingControlId); + if (receiver == null || receiver == this.ClientID) { + this.ProcessResponse(response); + this.AuthenticationProcessedAlready = true; + } } - } + })); } } diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs index 9eb4f0e..4a52ee2 100644 --- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs @@ -15,6 +15,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System.Drawing.Design; using System.Globalization; using System.Linq; + using System.Net.Http; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -643,12 +644,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { string receiver = this.Page.Request.QueryString[ReturnToReceivingControlId] ?? this.Page.Request.Form[ReturnToReceivingControlId]; if (receiver == this.ClientID || (receiver == null && !this.IsEmbeddedInParentOpenIdControl)) { - var response = Task.Run(() => this.RelyingParty.GetResponseAsync(new HttpRequestWrapper(this.Context.Request), CancellationToken.None)).GetAwaiter().GetResult(); - Logger.Controls.DebugFormat( - "The {0} control checked for an authentication response and found: {1}", - this.ID, - response != null ? response.Status.ToString() : "nothing"); - this.ProcessResponse(response); + this.Page.RegisterAsyncTask(new PageAsyncTask( + async ct => { + var response = + await this.RelyingParty.GetResponseAsync(new HttpRequestWrapper(this.Context.Request), ct); + Logger.Controls.DebugFormat( + "The {0} control checked for an authentication response and found: {1}", + this.ID, + response != null ? response.Status.ToString() : "nothing"); + this.ProcessResponse(response); + })); } } @@ -853,16 +858,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <param name="writer">The HTML writer.</param> /// <param name="request">The outgoing authentication request.</param> /// <param name="windowStatus">The text to try to display in the status bar on mouse hover.</param> - protected async Task RenderOpenIdMessageTransmissionAsAnchorAttributesAsync(HtmlTextWriter writer, IAuthenticationRequest request, string windowStatus, CancellationToken cancellationToken) { + protected void RenderOpenIdMessageTransmissionAsAnchorAttributes(HtmlTextWriter writer, HttpResponseMessage response, string windowStatus) { Requires.NotNull(writer, "writer"); - Requires.NotNull(request, "request"); + Requires.NotNull(response, "response"); // We render a standard HREF attribute for non-javascript browsers. - var response = await request.GetRedirectingResponseAsync(cancellationToken); writer.AddAttribute(HtmlTextWriterAttribute.Href, response.GetDirectUriRequest().AbsoluteUri); // And for the Javascript ones we do the extra work to use form POST where necessary. - writer.AddAttribute(HtmlTextWriterAttribute.Onclick, await this.CreateGetOrPostAHrefValueAsync(request, cancellationToken) + " return false;"); + writer.AddAttribute(HtmlTextWriterAttribute.Onclick, this.CreateGetOrPostAHrefValue(response) + " return false;"); writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer"); if (!string.IsNullOrEmpty(windowStatus)) { @@ -1012,11 +1016,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </summary> /// <param name="request">The authentication request to send.</param> /// <returns>The javascript that should execute.</returns> - private async Task<string> CreateGetOrPostAHrefValueAsync(IAuthenticationRequest request, CancellationToken cancellationToken) { - Requires.NotNull(request, "request"); + private string CreateGetOrPostAHrefValue(HttpResponseMessage requestRedirectingResponse) { + Requires.NotNull(requestRedirectingResponse, "requestRedirectingResponse"); - var response = await request.GetRedirectingResponseAsync(cancellationToken); - Uri directUri = response.GetDirectUriRequest(); + Uri directUri = requestRedirectingResponse.GetDirectUriRequest(); return "window.dnoa_internal.GetOrPost(" + MessagingUtilities.GetSafeJavascriptValue(directUri.AbsoluteUri) + ");"; } |