summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/DotNetOpenAuth.OpenId.RelyingParty.UI.csproj2
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs71
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs10
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs16
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdLogin.cs7
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs96
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs76
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdSelector.cs5
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdTextBox.cs8
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty.UI/packages.config1
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs55
11 files changed, 205 insertions, 142 deletions
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/DotNetOpenAuth.OpenId.RelyingParty.UI.csproj b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/DotNetOpenAuth.OpenId.RelyingParty.UI.csproj
index 0d83940..e65d1c4 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/DotNetOpenAuth.OpenId.RelyingParty.UI.csproj
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/DotNetOpenAuth.OpenId.RelyingParty.UI.csproj
@@ -67,6 +67,8 @@
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="System" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.Helpers.dll</HintPath>
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
index 918efdf..b6cab0e 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
@@ -11,11 +11,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Globalization;
using System.Linq;
using System.Net;
+ using System.Net.Http;
+ using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;
-
using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Extensions;
@@ -63,8 +66,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <para>No exception is thrown if no OpenID endpoints were discovered.
/// An empty enumerable is returned instead.</para>
/// </remarks>
- public override IEnumerable<IAuthenticationRequest> CreateRequests(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl) {
- var requests = base.CreateRequests(userSuppliedIdentifier, realm, returnToUrl);
+ public override async Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl, CancellationToken cancellationToken) {
+ var requests = await base.CreateRequestsAsync(userSuppliedIdentifier, realm, returnToUrl, cancellationToken);
+ var results = new List<IAuthenticationRequest>();
// Alter the requests so that have AJAX characteristics.
// Some OPs may be listed multiple times (one with HTTPS and the other with HTTP, for example).
@@ -113,8 +117,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// http://www.nabble.com/Re:-Defining-how-OpenID-should-behave-with-fragments-in-the-return_to-url-p22694227.html
////TODO:
- yield return req;
+ results.Add(req);
}
+
+ return results;
}
/// <summary>
@@ -142,13 +148,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// }
/// </code>
/// </remarks>
- public OutgoingWebResponse AsAjaxDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
+ public async Task<HttpResponseMessage> AsAjaxDiscoveryResultAsync(IEnumerable<IAuthenticationRequest> requests, CancellationToken cancellationToken) {
Requires.NotNull(requests, "requests");
var serializer = new JavaScriptSerializer();
- return new OutgoingWebResponse {
- Body = serializer.Serialize(this.AsJsonDiscoveryResult(requests)),
+ var response = new HttpResponseMessage {
+ Content = new StringContent(serializer.Serialize(await this.AsJsonDiscoveryResultAsync(requests, cancellationToken))),
};
+ response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
+ return response;
}
/// <summary>
@@ -159,11 +167,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <returns>
/// The JSON result to return to the user agent.
/// </returns>
- public string AsAjaxPreloadedDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
+ public async Task<string> AsAjaxPreloadedDiscoveryResultAsync(IEnumerable<IAuthenticationRequest> requests, CancellationToken cancellationToken) {
Requires.NotNull(requests, "requests");
var serializer = new JavaScriptSerializer();
- string json = serializer.Serialize(this.AsJsonPreloadedDiscoveryResult(requests));
+ string json = serializer.Serialize(await this.AsJsonPreloadedDiscoveryResultAsync(requests, cancellationToken));
string script = "window.dnoa_internal.loadPreloadedDiscoveryResults(" + json + ");";
return script;
@@ -174,18 +182,27 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="requests">The discovery results from just <i>one</i> identifier to serialize as a JSON response.</param>
/// <returns>A JSON object, not yet serialized.</returns>
- internal object AsJsonDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
+ internal async Task<object> AsJsonDiscoveryResultAsync(IEnumerable<IAuthenticationRequest> requests, CancellationToken cancellationToken) {
Requires.NotNull(requests, "requests");
requests = requests.CacheGeneratedResults();
if (requests.Any()) {
+ var requestUrls =
+ requests.Select(
+ req =>
+ new {
+ endpoint = req.Provider.Uri.AbsoluteUri,
+ immediate = this.GetRedirectUrlAsync(req, true, cancellationToken),
+ setup = this.GetRedirectUrlAsync(req, false, cancellationToken),
+ }).ToList();
+ await Task.WhenAll(requestUrls.Select(r => r.immediate).Concat(requestUrls.Select(r => r.setup)));
return new {
claimedIdentifier = (string)requests.First().ClaimedIdentifier,
- requests = requests.Select(req => new {
- endpoint = req.Provider.Uri.AbsoluteUri,
- immediate = this.GetRedirectUrl(req, true),
- setup = this.GetRedirectUrl(req, false),
+ requests = requestUrls.Select(req => new {
+ endpoint = req.endpoint,
+ immediate = req.immediate.Result, // await already took place
+ setup = req.setup.Result, // await already took place
}).ToArray()
};
} else {
@@ -204,7 +221,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <returns>
/// A JSON object, not yet serialized to a string.
/// </returns>
- private object AsJsonPreloadedDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
+ private async Task<object> AsJsonPreloadedDiscoveryResultAsync(IEnumerable<IAuthenticationRequest> requests, CancellationToken cancellationToken) {
Requires.NotNull(requests, "requests");
// We prepare a JSON object with this interface:
@@ -214,13 +231,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// string userSuppliedIdentifier;
// jsonResponse discoveryResult; // contains result of call to SerializeDiscoveryAsJson(Identifier)
// }
- var json = (from request in requests
- group request by request.DiscoveryResult.UserSuppliedIdentifier into requestsByIdentifier
- select new {
- userSuppliedIdentifier = (string)requestsByIdentifier.Key,
- discoveryResult = this.AsJsonDiscoveryResult(requestsByIdentifier),
- }).ToArray();
-
+ var jsonAsync = (from request in requests
+ group request by request.DiscoveryResult.UserSuppliedIdentifier into requestsByIdentifier
+ select new {
+ userSuppliedIdentifier = (string)requestsByIdentifier.Key,
+ discoveryResult = this.AsJsonDiscoveryResultAsync(requestsByIdentifier, cancellationToken),
+ }).ToArray();
+ await Task.WhenAll(jsonAsync.Select(j => j.discoveryResult));
+ var json = from j in jsonAsync
+ select new {
+ userSuppliedIdentifier = j.userSuppliedIdentifier,
+ discoveryResult = j.discoveryResult.Result, // await happened previously
+ };
return json;
}
@@ -232,11 +254,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="immediate"><c>true</c>to create a checkid_immediate request;
/// <c>false</c> to create a checkid_setup request.</param>
/// <returns>The absolute URL that carries the entire OpenID message.</returns>
- private Uri GetRedirectUrl(IAuthenticationRequest request, bool immediate) {
+ private async Task<Uri> GetRedirectUrlAsync(IAuthenticationRequest request, bool immediate, CancellationToken cancellationToken) {
Requires.NotNull(request, "request");
request.Mode = immediate ? AuthenticationRequestMode.Immediate : AuthenticationRequestMode.Setup;
- return request.RedirectingResponse.GetDirectUriRequest(this.Channel);
+ var response = await request.GetRedirectingResponseAsync(cancellationToken);
+ return response.GetDirectUriRequest();
}
}
}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
index b5b6162..5900e7b 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
@@ -22,6 +22,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Drawing.Design;
using System.Globalization;
using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using DotNetOpenAuth.Messaging;
@@ -716,7 +718,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
loader.insert();
} } catch (e) { }";
- this.Page.ClientScript.RegisterClientScriptInclude("yuiloader", this.Page.Request.Url.IsTransportSecure() ? YuiLoaderHttps : YuiLoaderHttp);
+ this.Page.ClientScript.RegisterClientScriptInclude(
+ "yuiloader", this.Page.Request.Url.IsTransportSecure() ? YuiLoaderHttps : YuiLoaderHttp);
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "requiredYuiComponents", yuiLoadScript, true);
}
@@ -737,8 +740,9 @@ 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.
- if (this.Identifier != null && this.AuthenticationResponse == null) {
- this.PreloadDiscovery(this.Identifier);
+ var response = Task.Run(() => this.GetAuthenticationResponseAsync(CancellationToken.None)).GetAwaiter().GetResult();
+ if (this.Identifier != null && response == null) {
+ this.PreloadDiscoveryAsync(this.Identifier, CancellationToken.None).Wait();
}
}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs
index 505461a..ae962ed 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdButton.cs
@@ -13,6 +13,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Globalization;
using System.Linq;
using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using System.Web;
using System.Web.UI;
using DotNetOpenAuth.Messaging;
@@ -117,8 +120,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
protected override void RaisePostBackEvent(string eventArgument) {
if (!this.PrecreateRequest) {
try {
- IAuthenticationRequest request = this.CreateRequests().First();
- request.RedirectToProvider();
+ // 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);
}
@@ -148,9 +156,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
} else {
string tooltip = this.Text;
if (this.PrecreateRequest && !this.DesignMode) {
- IAuthenticationRequest request = this.CreateRequests().FirstOrDefault();
+ IAuthenticationRequest request = Task.Run(() => this.CreateRequestsAsync(CancellationToken.None)).GetAwaiter().GetResult().FirstOrDefault();
if (request != null) {
- RenderOpenIdMessageTransmissionAsAnchorAttributes(writer, request, tooltip);
+ this.RenderOpenIdMessageTransmissionAsAnchorAttributesAsync(writer, request, tooltip, CancellationToken.None).Wait();
} else {
tooltip = OpenIdStrings.OpenIdEndpointNotFound;
}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdLogin.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdLogin.cs
index 16f9462..d6ce3ce 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdLogin.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdLogin.cs
@@ -10,6 +10,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
+ using System.Threading;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
@@ -933,14 +934,14 @@ idselector_input_id = '" + this.ClientID + @"';
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- private void LoginButton_Click(object sender, EventArgs e) {
+ private async void LoginButton_Click(object sender, EventArgs e) {
if (!this.Page.IsValid) {
return;
}
- IAuthenticationRequest request = this.CreateRequests().FirstOrDefault();
+ IAuthenticationRequest request = (await this.CreateRequestsAsync(CancellationToken.None)).FirstOrDefault();
if (request != null) {
- this.LogOn(request);
+ await this.LogOnAsync(request, CancellationToken.None);
} else {
if (!string.IsNullOrEmpty(this.FailedMessageText)) {
this.errorLabel.Text = string.Format(CultureInfo.CurrentCulture, this.FailedMessageText, 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 9b4d271..0d5435d 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
@@ -13,7 +13,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
+ using System.Net.Http;
using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
@@ -169,38 +172,36 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets the completed authentication response.
/// </summary>
- public IAuthenticationResponse AuthenticationResponse {
- get {
- if (this.authenticationResponse == null) {
- // We will either validate a new response and return a live AuthenticationResponse
- // or we will try to deserialize a previous IAuthenticationResponse (snapshot)
- // from viewstate and return that.
- IAuthenticationResponse viewstateResponse = this.ViewState[AuthenticationResponseViewStateKey] as IAuthenticationResponse;
- string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
- string formAuthData = this.Page.Request.Form[this.OpenIdAuthDataFormKey];
-
- // First see if there is fresh auth data to be processed into a response.
- if (!string.IsNullOrEmpty(formAuthData) && !string.Equals(viewstateAuthData, formAuthData, StringComparison.Ordinal)) {
- this.ViewState[AuthDataViewStateKey] = formAuthData;
-
- HttpRequestBase clientResponseInfo = new HttpRequestInfo("GET", new Uri(formAuthData));
- this.authenticationResponse = this.RelyingParty.GetResponse(clientResponseInfo);
- Logger.Controls.DebugFormat(
- "The {0} control checked for an authentication response and found: {1}",
- this.ID,
- this.authenticationResponse.Status);
- this.AuthenticationProcessedAlready = false;
-
- // Save out the authentication response to viewstate so we can find it on
- // a subsequent postback.
- this.ViewState[AuthenticationResponseViewStateKey] = new PositiveAuthenticationResponseSnapshot(this.authenticationResponse);
- } else {
- this.authenticationResponse = viewstateResponse;
- }
+ public async Task<IAuthenticationResponse> GetAuthenticationResponseAsync(CancellationToken cancellationToken) {
+ if (this.authenticationResponse == null) {
+ // We will either validate a new response and return a live AuthenticationResponse
+ // or we will try to deserialize a previous IAuthenticationResponse (snapshot)
+ // from viewstate and return that.
+ IAuthenticationResponse viewstateResponse = this.ViewState[AuthenticationResponseViewStateKey] as IAuthenticationResponse;
+ string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
+ string formAuthData = this.Page.Request.Form[this.OpenIdAuthDataFormKey];
+
+ // First see if there is fresh auth data to be processed into a response.
+ if (!string.IsNullOrEmpty(formAuthData) && !string.Equals(viewstateAuthData, formAuthData, StringComparison.Ordinal)) {
+ this.ViewState[AuthDataViewStateKey] = formAuthData;
+
+ HttpRequestBase clientResponseInfo = new HttpRequestInfo("GET", new Uri(formAuthData));
+ this.authenticationResponse = await this.RelyingParty.GetResponseAsync(clientResponseInfo, cancellationToken);
+ Logger.Controls.DebugFormat(
+ "The {0} control checked for an authentication response and found: {1}",
+ this.ID,
+ this.authenticationResponse.Status);
+ this.AuthenticationProcessedAlready = false;
+
+ // Save out the authentication response to viewstate so we can find it on
+ // a subsequent postback.
+ this.ViewState[AuthenticationResponseViewStateKey] = new PositiveAuthenticationResponseSnapshot(this.authenticationResponse);
+ } else {
+ this.authenticationResponse = viewstateResponse;
}
-
- return this.authenticationResponse;
}
+
+ return this.authenticationResponse;
}
/// <summary>
@@ -278,7 +279,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Processes a callback event that targets a control.
/// </summary>
/// <param name="eventArgument">A string that represents an event argument to pass to the event handler.</param>
- [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "We want to preserve the signature of the interface.")]
+ [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",
+ Justification = "We want to preserve the signature of the interface.")]
protected virtual void RaiseCallbackEvent(string eventArgument) {
string userSuppliedIdentifier = eventArgument;
@@ -288,8 +290,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
this.Identifier = userSuppliedIdentifier;
var serializer = new JavaScriptSerializer();
- IEnumerable<IAuthenticationRequest> requests = this.CreateRequests(this.Identifier);
- this.discoveryResult = serializer.Serialize(this.AjaxRelyingParty.AsJsonDiscoveryResult(requests));
+ 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();
}
/// <summary>
@@ -306,8 +310,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// user agent for javascript as soon as the page loads.
/// </summary>
/// <param name="identifier">The identifier.</param>
- protected void PreloadDiscovery(Identifier identifier) {
- this.PreloadDiscovery(new[] { identifier });
+ protected Task PreloadDiscoveryAsync(Identifier identifier, CancellationToken cancellationToken) {
+ return this.PreloadDiscoveryAsync(new[] { identifier }, cancellationToken);
}
/// <summary>
@@ -315,9 +319,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// user agent for javascript as soon as the page loads.
/// </summary>
/// <param name="identifiers">The identifiers to perform discovery on.</param>
- protected void PreloadDiscovery(IEnumerable<Identifier> identifiers) {
- string script = this.AjaxRelyingParty.AsAjaxPreloadedDiscoveryResult(
- identifiers.SelectMany(id => this.CreateRequests(id)));
+ protected async Task PreloadDiscoveryAsync(IEnumerable<Identifier> identifiers, CancellationToken cancellationToken) {
+ var requests = await Task.WhenAll(identifiers.Select(id => this.CreateRequestsAsync(id, cancellationToken)));
+ string script = await this.AjaxRelyingParty.AsAjaxPreloadedDiscoveryResultAsync(requests.SelectMany(r => r), cancellationToken);
this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyAjaxControlBase), this.ClientID, script, true);
}
@@ -342,12 +346,13 @@ 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) {
- if (this.AuthenticationResponse != null && !this.AuthenticationProcessedAlready) {
+ 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 = this.AuthenticationResponse.GetUntrustedCallbackArgument(ReturnToReceivingControlId);
+ string receiver = response.GetUntrustedCallbackArgument(ReturnToReceivingControlId);
if (receiver == null || receiver == this.ClientID) {
- this.ProcessResponse(this.AuthenticationResponse);
+ this.ProcessResponse(response);
this.AuthenticationProcessedAlready = true;
}
}
@@ -413,16 +418,17 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Notifies the user agent via an AJAX response of a completed authentication attempt.
/// </summary>
- protected override void ScriptClosingPopupOrIFrame() {
+ protected override async Task ScriptClosingPopupOrIFrameAsync(CancellationToken cancellationToken) {
Action<AuthenticationStatus> callback = status => {
if (status == AuthenticationStatus.Authenticated) {
this.OnUnconfirmedPositiveAssertion(); // event handler will fill the clientScriptExtensions collection.
}
};
- OutgoingWebResponse response = this.RelyingParty.ProcessResponseFromPopup(
- this.RelyingParty.Channel.GetRequestFromContext(),
- callback);
+ HttpResponseMessage response = await this.RelyingParty.ProcessResponseFromPopupAsync(
+ new HttpRequestWrapper(this.Context.Request),
+ callback,
+ cancellationToken);
response.Send();
}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
index 7d616d2..14adf3c 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
@@ -17,6 +17,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+ using System.Threading;
+ using System.Threading.Tasks;
using System.Web;
using System.Web.Security;
using System.Web.UI;
@@ -363,7 +365,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
if (Page != null && !DesignMode) {
// Validate new value by trying to construct a Realm object based on it.
- new Realm(OpenIdUtilities.GetResolvedRealm(this.Page, value, this.RelyingParty.Channel.GetRequestFromContext())); // throws an exception on failure.
+ new Realm(OpenIdUtilities.GetResolvedRealm(this.Page, value, new HttpRequestWrapper(this.Context.Request))); // throws an exception on failure.
} else {
// We can't fully test it, but it should start with either ~/ or a protocol.
if (Regex.IsMatch(value, @"^https?://")) {
@@ -395,7 +397,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
set {
if (this.Page != null && !this.DesignMode) {
// Validate new value by trying to construct a Uri based on it.
- new Uri(this.RelyingParty.Channel.GetRequestFromContext().GetPublicFacingUrl(), this.Page.ResolveUrl(value)); // throws an exception on failure.
+ new Uri(new HttpRequestWrapper(this.Context.Request).GetPublicFacingUrl(), this.Page.ResolveUrl(value)); // throws an exception on failure.
} else {
// We can't fully test it, but it should start with either ~/ or a protocol.
if (Regex.IsMatch(value, @"^https?://")) {
@@ -510,10 +512,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Immediately redirects to the OpenID Provider to verify the Identifier
/// provided in the text box.
/// </summary>
- public void LogOn() {
- IAuthenticationRequest request = this.CreateRequests().FirstOrDefault();
+ public async Task LogOnAsync(CancellationToken cancellationToken) {
+ IAuthenticationRequest request = (await this.CreateRequestsAsync(cancellationToken)).FirstOrDefault();
ErrorUtilities.VerifyProtocol(request != null, OpenIdStrings.OpenIdEndpointNotFound);
- this.LogOn(request);
+ await this.LogOnAsync(request, cancellationToken);
}
/// <summary>
@@ -521,13 +523,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// provided in the text box.
/// </summary>
/// <param name="request">The request.</param>
- public void LogOn(IAuthenticationRequest request) {
+ public async Task LogOnAsync(IAuthenticationRequest request, CancellationToken cancellationToken) {
Requires.NotNull(request, "request");
if (this.IsPopupAppropriate(request)) {
- this.ScriptPopupWindow(request);
+ await this.ScriptPopupWindowAsync(request, cancellationToken);
} else {
- request.RedirectToProvider();
+ await request.RedirectToProviderAsync(cancellationToken: cancellationToken);
}
}
@@ -561,17 +563,17 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// A sequence of authentication requests, any one of which may be
/// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
/// </returns>
- protected internal virtual IEnumerable<IAuthenticationRequest> CreateRequests(Identifier identifier) {
+ protected internal virtual Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(Identifier identifier, CancellationToken cancellationToken) {
Requires.NotNull(identifier, "identifier");
// If this control is actually a member of another OpenID RP control,
// delegate creation of requests to the parent control.
var parentOwner = this.ParentControls.OfType<OpenIdRelyingPartyControlBase>().FirstOrDefault();
if (parentOwner != null) {
- return parentOwner.CreateRequests(identifier);
+ return parentOwner.CreateRequestsAsync(identifier, cancellationToken);
} else {
// Delegate to a private method to keep 'yield return' and Code Contract separate.
- return this.CreateRequestsCore(identifier);
+ return this.CreateRequestsCoreAsync(identifier, cancellationToken);
}
}
@@ -603,9 +605,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// A sequence of authentication requests, any one of which may be
/// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
/// </returns>
- protected IEnumerable<IAuthenticationRequest> CreateRequests() {
+ protected Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(CancellationToken cancellationToken) {
RequiresEx.ValidState(this.Identifier != null, OpenIdStrings.NoIdentifierSet);
- return this.CreateRequests(this.Identifier);
+ return this.CreateRequestsAsync(this.Identifier, cancellationToken);
}
/// <summary>
@@ -626,10 +628,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// Take an unreliable sneek peek to see if we're in a popup and an OpenID
// assertion is coming in. We shouldn't process assertions in a popup window.
- if (this.Page.Request.QueryString[UIPopupCallbackKey] == "1" && this.Page.Request.QueryString[UIPopupCallbackParentKey] == null) {
+ if (this.Page.Request.QueryString[UIPopupCallbackKey] == "1"
+ && this.Page.Request.QueryString[UIPopupCallbackParentKey] == null) {
// We're in a popup window. We need to close it and pass the
// message back to the parent window for processing.
- this.ScriptClosingPopupOrIFrame();
+ this.ScriptClosingPopupOrIFrameAsync(CancellationToken.None).Wait();
return; // don't do any more processing on it now
}
@@ -637,9 +640,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// Note that Stateless mode causes no receiver to be indicated, and
// we want to handle that, but only if there isn't a parent control that
// will be handling that.
- string receiver = this.Page.Request.QueryString[ReturnToReceivingControlId] ?? this.Page.Request.Form[ReturnToReceivingControlId];
+ string receiver = this.Page.Request.QueryString[ReturnToReceivingControlId]
+ ?? this.Page.Request.Form[ReturnToReceivingControlId];
if (receiver == this.ClientID || (receiver == null && !this.IsEmbeddedInParentOpenIdControl)) {
- var response = this.RelyingParty.GetResponse();
+ 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,
@@ -651,8 +655,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Notifies the user agent via an AJAX response of a completed authentication attempt.
/// </summary>
- protected virtual void ScriptClosingPopupOrIFrame() {
- this.RelyingParty.ProcessResponseFromPopup();
+ protected virtual Task ScriptClosingPopupOrIFrameAsync(CancellationToken cancellationToken) {
+ return this.RelyingParty.ProcessResponseFromPopupAsync(cancellationToken);
}
/// <summary>
@@ -792,7 +796,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <returns>The instantiated relying party.</returns>
protected OpenIdRelyingParty CreateRelyingParty() {
- IOpenIdApplicationStore store = this.Stateless ? null : OpenIdElement.Configuration.RelyingParty.ApplicationStore.CreateInstance(OpenIdRelyingParty.HttpApplicationStore);
+ IOpenIdApplicationStore store = this.Stateless ? null : OpenIdElement.Configuration.RelyingParty.ApplicationStore.CreateInstance(OpenIdRelyingParty.GetHttpApplicationStore(new HttpContextWrapper(this.Context)), null);
return this.CreateRelyingParty(store);
}
@@ -849,15 +853,16 @@ 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 void RenderOpenIdMessageTransmissionAsAnchorAttributes(HtmlTextWriter writer, IAuthenticationRequest request, string windowStatus) {
+ protected async Task RenderOpenIdMessageTransmissionAsAnchorAttributesAsync(HtmlTextWriter writer, IAuthenticationRequest request, string windowStatus, CancellationToken cancellationToken) {
Requires.NotNull(writer, "writer");
Requires.NotNull(request, "request");
// We render a standard HREF attribute for non-javascript browsers.
- writer.AddAttribute(HtmlTextWriterAttribute.Href, request.RedirectingResponse.GetDirectUriRequest(this.RelyingParty.Channel).AbsoluteUri);
+ 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, this.CreateGetOrPostAHrefValue(request) + " return false;");
+ writer.AddAttribute(HtmlTextWriterAttribute.Onclick, await this.CreateGetOrPostAHrefValueAsync(request, cancellationToken) + " return false;");
writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
if (!string.IsNullOrEmpty(windowStatus)) {
@@ -910,16 +915,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// A sequence of authentication requests, any one of which may be
/// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
/// </returns>
- private IEnumerable<IAuthenticationRequest> CreateRequestsCore(Identifier identifier) {
+ private async Task<IEnumerable<IAuthenticationRequest>> CreateRequestsCoreAsync(Identifier identifier, CancellationToken cancellationToken) {
ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier"); // NO CODE CONTRACTS! (yield return used here)
IEnumerable<IAuthenticationRequest> requests;
+ var requestContext = new HttpRequestWrapper(this.Context.Request);
+ var results = new List<IAuthenticationRequest>();
// Approximate the returnTo (either based on the customize property or the page URL)
// so we can use it to help with Realm resolution.
Uri returnToApproximation;
if (this.ReturnToUrl != null) {
string returnToResolvedPath = this.ResolveUrl(this.ReturnToUrl);
- returnToApproximation = new Uri(this.RelyingParty.Channel.GetRequestFromContext().GetPublicFacingUrl(), returnToResolvedPath);
+ returnToApproximation = new Uri(requestContext.GetPublicFacingUrl(), returnToResolvedPath);
} else {
returnToApproximation = this.Page.Request.Url;
}
@@ -927,7 +934,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// Resolve the trust root, and swap out the scheme and port if necessary to match the
// return_to URL, since this match is required by OpenID, and the consumer app
// may be using HTTP at some times and HTTPS at others.
- UriBuilder realm = OpenIdUtilities.GetResolvedRealm(this.Page, this.RealmUrl, this.RelyingParty.Channel.GetRequestFromContext());
+ UriBuilder realm = OpenIdUtilities.GetResolvedRealm(this.Page, this.RealmUrl, requestContext);
realm.Scheme = returnToApproximation.Scheme;
realm.Port = returnToApproximation.Port;
@@ -936,11 +943,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// might slip through our validator control if it is disabled.
Realm typedRealm = new Realm(realm);
if (string.IsNullOrEmpty(this.ReturnToUrl)) {
- requests = this.RelyingParty.CreateRequests(identifier, typedRealm);
+ requests = await this.RelyingParty.CreateRequestsAsync(identifier, typedRealm, requestContext);
} else {
// Since the user actually gave us a return_to value,
// the "approximation" is exactly what we want.
- requests = this.RelyingParty.CreateRequests(identifier, typedRealm, returnToApproximation);
+ requests = await this.RelyingParty.CreateRequestsAsync(identifier, typedRealm, returnToApproximation, cancellationToken);
}
// Some OPs may be listed multiple times (one with HTTPS and the other with HTTP, for example).
@@ -993,9 +1000,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// change its value and have that value saved.
req.SetUntrustedCallbackArgument(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString());
- yield return req;
+ results.Add(req);
}
}
+
+ return results;
}
/// <summary>
@@ -1003,10 +1012,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="request">The authentication request to send.</param>
/// <returns>The javascript that should execute.</returns>
- private string CreateGetOrPostAHrefValue(IAuthenticationRequest request) {
+ private async Task<string> CreateGetOrPostAHrefValueAsync(IAuthenticationRequest request, CancellationToken cancellationToken) {
Requires.NotNull(request, "request");
- Uri directUri = request.RedirectingResponse.GetDirectUriRequest(this.RelyingParty.Channel);
+ var response = await request.GetRedirectingResponseAsync(cancellationToken);
+ Uri directUri = response.GetDirectUriRequest();
return "window.dnoa_internal.GetOrPost(" + MessagingUtilities.GetSafeJavascriptValue(directUri.AbsoluteUri) + ");";
}
@@ -1014,7 +1024,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Wires the return page to immediately display a popup window with the Provider in it.
/// </summary>
/// <param name="request">The request.</param>
- private void ScriptPopupWindow(IAuthenticationRequest request) {
+ private async Task ScriptPopupWindowAsync(IAuthenticationRequest request, CancellationToken cancellationToken) {
Requires.NotNull(request, "request");
RequiresEx.ValidState(this.RelyingParty != null);
@@ -1027,7 +1037,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
startupScript.AppendLine("window.dnoa_internal.popupWindow = function() {");
startupScript.AppendFormat(
@"\tvar openidPopup = {0}",
- OpenId.RelyingParty.Extensions.UI.UIUtilities.GetWindowPopupScript(this.RelyingParty, request, "openidPopup"));
+ await OpenId.RelyingParty.Extensions.UI.UIUtilities.GetWindowPopupScriptAsync(this.RelyingParty, request, "openidPopup", cancellationToken));
startupScript.AppendLine("};");
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "loginPopup", startupScript.ToString(), true);
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdSelector.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdSelector.cs
index 7881a8b..a1c4510 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdSelector.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdSelector.cs
@@ -16,6 +16,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.IdentityModel.Claims;
using System.Linq;
using System.Text;
+ using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
@@ -317,7 +318,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
this.positiveAssertionField.ClientID);
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Postback", script, true);
- this.PreloadDiscovery(this.Buttons.OfType<SelectorProviderButton>().Select(op => op.OPIdentifier).Where(id => id != null));
+ this.PreloadDiscoveryAsync(
+ this.Buttons.OfType<SelectorProviderButton>().Select(op => op.OPIdentifier).Where(id => id != null),
+ CancellationToken.None).Wait();
this.textBox.Visible = this.OpenIdTextBoxVisible;
}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdTextBox.cs
index 7474854..9a5daf8 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdTextBox.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/OpenId/RelyingParty/OpenIdTextBox.cs
@@ -20,6 +20,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
+ using System.Threading;
+ using System.Threading.Tasks;
using System.Web;
using System.Web.Security;
using System.Web.UI;
@@ -550,12 +552,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// A sequence of authentication requests, any one of which may be
/// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
/// </returns>
- protected internal override IEnumerable<IAuthenticationRequest> CreateRequests(Identifier identifier) {
+ protected internal override async Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(Identifier identifier, CancellationToken cancellationToken) {
ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
// We delegate all our logic to another method, since invoking base. methods
// within an iterator method results in unverifiable code.
- return this.CreateRequestsCore(base.CreateRequests(identifier));
+ return this.CreateRequestsCore(await base.CreateRequestsAsync(identifier, cancellationToken));
}
/// <summary>
@@ -696,7 +698,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
Language = this.RequestLanguage,
TimeZone = this.RequestTimeZone,
PolicyUrl = string.IsNullOrEmpty(this.PolicyUrl) ?
- null : new Uri(this.RelyingParty.Channel.GetRequestFromContext().GetPublicFacingUrl(), this.Page.ResolveUrl(this.PolicyUrl)),
+ null : new Uri(new HttpRequestWrapper(this.Context.Request).GetPublicFacingUrl(), this.Page.ResolveUrl(this.PolicyUrl)),
};
// Only actually add the extension request if fields are actually being requested.
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/packages.config b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/packages.config
index e68b4a4..d0cb981 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty.UI/packages.config
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty.UI/packages.config
@@ -3,6 +3,7 @@
<package id="Microsoft.AspNet.Mvc" version="3.0.20105.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="1.0.20105.408" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="1.0.20105.408" targetFramework="net45" />
+ <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Validation" version="2.0.1.12362" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs
index 2ffc016..1841f6a 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs
@@ -96,7 +96,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Initializes a new instance of the <see cref="OpenIdRelyingParty"/> class.
/// </summary>
public OpenIdRelyingParty()
- : this(OpenIdElement.Configuration.RelyingParty.ApplicationStore.CreateInstance(HttpApplicationStore, null)) {
+ : this(OpenIdElement.Configuration.RelyingParty.ApplicationStore.CreateInstance(GetHttpApplicationStore(), null)) {
}
/// <summary>
@@ -161,24 +161,25 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// HttpApplication state dictionary to store associations and nonces.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Advanced)]
- public static IOpenIdApplicationStore HttpApplicationStore {
- get {
- HttpContext context = HttpContext.Current;
- ErrorUtilities.VerifyOperation(context != null, Strings.StoreRequiredWhenNoHttpContextAvailable, typeof(IOpenIdApplicationStore).Name);
- var store = (IOpenIdApplicationStore)context.Application[ApplicationStoreKey];
- if (store == null) {
- context.Application.Lock();
- try {
- if ((store = (IOpenIdApplicationStore)context.Application[ApplicationStoreKey]) == null) {
- context.Application[ApplicationStoreKey] = store = new StandardRelyingPartyApplicationStore();
- }
- } finally {
- context.Application.UnLock();
+ public static IOpenIdApplicationStore GetHttpApplicationStore(HttpContextBase context = null) {
+ if (context == null) {
+ ErrorUtilities.VerifyOperation(HttpContext.Current != null, Strings.StoreRequiredWhenNoHttpContextAvailable, typeof(IOpenIdApplicationStore).Name);
+ context = new HttpContextWrapper(HttpContext.Current);
+ }
+
+ var store = (IOpenIdApplicationStore)context.Application[ApplicationStoreKey];
+ if (store == null) {
+ context.Application.Lock();
+ try {
+ if ((store = (IOpenIdApplicationStore)context.Application[ApplicationStoreKey]) == null) {
+ context.Application[ApplicationStoreKey] = store = new StandardRelyingPartyApplicationStore();
}
+ } finally {
+ context.Application.UnLock();
}
-
- return store;
}
+
+ return store;
}
/// <summary>
@@ -394,10 +395,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
- public async Task<IAuthenticationRequest> CreateRequestAsync(Identifier userSuppliedIdentifier) {
+ public async Task<IAuthenticationRequest> CreateRequestAsync(Identifier userSuppliedIdentifier, HttpRequestBase requestContext = null) {
Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
try {
- return (await this.CreateRequestsAsync(userSuppliedIdentifier)).First();
+ return (await this.CreateRequestsAsync(userSuppliedIdentifier, requestContext)).First();
} catch (InvalidOperationException ex) {
throw ErrorUtilities.Wrap(ex, OpenIdStrings.OpenIdEndpointNotFound);
}
@@ -464,30 +465,33 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <para>Requires an <see cref="HttpContext.Current">HttpContext.Current</see> context.</para>
/// </remarks>
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
- public async Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(Identifier userSuppliedIdentifier, Realm realm) {
- RequiresEx.ValidState(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
+ public async Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(Identifier userSuppliedIdentifier, Realm realm, HttpRequestBase requestContext = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ RequiresEx.ValidState(requestContext != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
Requires.NotNull(realm, "realm");
+ requestContext = requestContext ?? this.channel.GetRequestFromContext();
+
// This next code contract is a BAD idea, because it causes each authentication request to be generated
// at least an extra time.
////
// Build the return_to URL
- UriBuilder returnTo = new UriBuilder(this.Channel.GetRequestFromContext().GetPublicFacingUrl());
+ UriBuilder returnTo = new UriBuilder(requestContext.GetPublicFacingUrl());
// Trim off any parameters with an "openid." prefix, and a few known others
// to avoid carrying state from a prior login attempt.
returnTo.Query = string.Empty;
- NameValueCollection queryParams = this.Channel.GetRequestFromContext().GetQueryStringBeforeRewriting();
+ NameValueCollection queryParams = requestContext.GetQueryStringBeforeRewriting();
var returnToParams = new Dictionary<string, string>(queryParams.Count);
foreach (string key in queryParams) {
if (!IsOpenIdSupportingParameter(key) && key != null) {
returnToParams.Add(key, queryParams[key]);
}
}
+
returnTo.AppendQueryArgs(returnToParams);
- return await this.CreateRequestsAsync(userSuppliedIdentifier, realm, returnTo.Uri);
+ return await this.CreateRequestsAsync(userSuppliedIdentifier, realm, returnTo.Uri, cancellationToken);
}
/// <summary>
@@ -510,11 +514,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <para>Requires an <see cref="HttpContext.Current">HttpContext.Current</see> context.</para>
/// </remarks>
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
- public async Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(Identifier userSuppliedIdentifier) {
+ public async Task<IEnumerable<IAuthenticationRequest>> CreateRequestsAsync(Identifier userSuppliedIdentifier, HttpRequestBase requestContext = null, CancellationToken cancellationToken = default(CancellationToken)) {
Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
- RequiresEx.ValidState(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
- return await this.CreateRequestsAsync(userSuppliedIdentifier, Realm.AutoDetect);
+ return await this.CreateRequestsAsync(userSuppliedIdentifier, Realm.AutoDetect, requestContext, cancellationToken);
}
/// <summary>