summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-03-06 14:55:50 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2009-03-06 15:01:02 -0800
commit58669d51de6db631c3b56a53e4a7aa5a384e5fec (patch)
tree25c1688096a20b9b2094ec1fd11697ae651b30d8
parent83384150efcda894097e9e2a4448994361b8a626 (diff)
downloadDotNetOpenAuth-58669d51de6db631c3b56a53e4a7aa5a384e5fec.zip
DotNetOpenAuth-58669d51de6db631c3b56a53e4a7aa5a384e5fec.tar.gz
DotNetOpenAuth-58669d51de6db631c3b56a53e4a7aa5a384e5fec.tar.bz2
Refactoring around Provider's IRequest to process responses differently.
This is a step toward serializable IRequest objects.
-rw-r--r--samples/OpenIdProviderWebForms/Provider.ashx.cs19
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.cs8
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs7
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs4
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Provider/AuthenticationRequestTest.cs6
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs2
-rw-r--r--src/DotNetOpenAuth.TestWeb/OpenIdProviderEndpoint.ashx2
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs90
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs22
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/IRequest.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs30
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs74
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/Request.cs3
15 files changed, 160 insertions, 121 deletions
diff --git a/samples/OpenIdProviderWebForms/Provider.ashx.cs b/samples/OpenIdProviderWebForms/Provider.ashx.cs
index 5257a5d..40acc04 100644
--- a/samples/OpenIdProviderWebForms/Provider.ashx.cs
+++ b/samples/OpenIdProviderWebForms/Provider.ashx.cs
@@ -18,13 +18,12 @@
}
public void ProcessRequest(HttpContext context) {
- OpenIdProvider provider = new OpenIdProvider();
- IRequest request = provider.GetRequest();
+ IRequest request = ProviderEndpoint.Provider.GetRequest();
if (request != null) {
// Some OpenID requests are automatable and can be responded to immediately.
+ // But authentication requests cannot be responded to until something on
+ // this site decides whether to approve or disapprove the authentication.
if (!request.IsResponseReady) {
- // But authentication requests cannot be responded to until something on
- // this site decides whether to approve or disapprove the authentication.
var idrequest = (IAuthenticationRequest)request;
// We store the authentication request in the user's session so that
@@ -42,17 +41,17 @@
// to log this user in. If any UI needs to be presented to the user,
// the previous call to ProcessAuthenticationChallenge MAY not return
// due to a redirect to some ASPX page.
- } else {
- // Some other automatable OpenID request is coming down, so clear
- // any previously session stored authentication request that might be
- // stored for this user.
- ProviderEndpoint.PendingAuthenticationRequest = null;
}
// Whether this was an automated message or an authentication message,
// if there is a response ready to send back immediately, do so.
if (request.IsResponseReady) {
- request.Response.Send();
+ // We DON'T use ProviderEndpoint.SendResponse because
+ // that only sends responses to requests in PendingAuthenticationRequest,
+ // but we don't set that for associate and other non-checkid requests.
+ ProviderEndpoint.Provider.SendResponse(request);
+
+ // Make sure that any PendingAuthenticationRequest that MAY be set is cleared.
ProviderEndpoint.PendingAuthenticationRequest = null;
}
}
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.cs b/samples/OpenIdProviderWebForms/decide.aspx.cs
index 1ca0138..777a688 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx.cs
+++ b/samples/OpenIdProviderWebForms/decide.aspx.cs
@@ -20,7 +20,7 @@ namespace OpenIdProviderWebForms {
ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier = Code.Util.BuildIdentityUrl();
}
this.relyingPartyVerificationResultLabel.Text =
- ProviderEndpoint.PendingAuthenticationRequest.IsReturnUrlDiscoverable ? "passed" : "failed";
+ ProviderEndpoint.PendingAuthenticationRequest.IsReturnUrlDiscoverable(ProviderEndpoint.Provider.Channel.WebRequestHandler) ? "passed" : "failed";
this.identityUrlLabel.Text = ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier.ToString();
this.realmLabel.Text = ProviderEndpoint.PendingAuthenticationRequest.Realm.ToString();
@@ -61,15 +61,13 @@ namespace OpenIdProviderWebForms {
ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = true;
Debug.Assert(ProviderEndpoint.PendingAuthenticationRequest.IsResponseReady, "Setting authentication should be all that's necessary.");
- ProviderEndpoint.PendingAuthenticationRequest.Response.Send();
- ProviderEndpoint.PendingAuthenticationRequest = null;
+ ProviderEndpoint.SendResponse();
}
protected void No_Click(object sender, EventArgs e) {
ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = false;
Debug.Assert(ProviderEndpoint.PendingAuthenticationRequest.IsResponseReady, "Setting authentication should be all that's necessary.");
- ProviderEndpoint.PendingAuthenticationRequest.Response.Send();
- ProviderEndpoint.PendingAuthenticationRequest = null;
+ ProviderEndpoint.SendResponse();
}
}
} \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs b/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs
index 01c2cf5..94c0671 100644
--- a/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs
@@ -87,7 +87,7 @@ namespace DotNetOpenAuth.Test.OpenId {
// Ensure that the response is a suggestion that the RP try again with HMAC-SHA1
AssociateUnsuccessfulResponse renegotiateResponse = (AssociateUnsuccessfulResponse)reqAccessor.ResponseMessage;
Assert.AreEqual(protocol.Args.SignatureAlgorithm.HMAC_SHA1, renegotiateResponse.AssociationType);
- req.Response.Send();
+ op.SendResponse(req);
// Receive second attempt request for an HMAC-SHA1 association.
req = (AutoResponsiveRequest)op.GetRequest();
@@ -98,7 +98,7 @@ namespace DotNetOpenAuth.Test.OpenId {
// Ensure that the response is a success response.
AssociateSuccessfulResponse successResponse = (AssociateSuccessfulResponse)reqAccessor.ResponseMessage;
Assert.AreEqual(protocol.Args.SignatureAlgorithm.HMAC_SHA1, successResponse.AssociationType);
- req.Response.Send();
+ op.SendResponse(req);
});
coordinator.Run();
}
@@ -307,8 +307,7 @@ namespace DotNetOpenAuth.Test.OpenId {
IRequest req = op.GetRequest();
Assert.IsNotNull(req, "Expected incoming request but did not receive it.");
Assert.IsTrue(req.IsResponseReady);
- UserAgentResponse resp = req.Response;
- resp.Send();
+ op.SendResponse(req);
});
coordinator.IncomingMessageFilter = message => {
Assert.AreSame(opDescription.ProtocolVersion, message.Version, "The message was recognized as version {0} but was expected to be {1}.", message.Version, opDescription.ProtocolVersion);
diff --git a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
index 764e830..a19df2a 100644
--- a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
@@ -125,10 +125,10 @@ namespace DotNetOpenAuth.Test.OpenId.ChannelElements {
op => {
RegisterMockExtension(op.Channel);
op.Channel.Send(CreateResponseWithExtensions(protocol));
- op.GetRequest().Response.Send(); // check_auth
+ op.SendResponse(op.GetRequest()); // check_auth
op.SecuritySettings.SignOutgoingExtensions = false;
op.Channel.Send(CreateResponseWithExtensions(protocol));
- op.GetRequest().Response.Send(); // check_auth
+ op.SendResponse(op.GetRequest()); // check_auth
});
coordinator.Run();
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs
index b45dc1b..58eb4f4 100644
--- a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs
@@ -154,7 +154,7 @@ namespace DotNetOpenAuth.Test.OpenId {
}
}
- request.Response.Send();
+ provider.SendResponse(request);
}
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/Provider/AuthenticationRequestTest.cs b/src/DotNetOpenAuth.Test/OpenId/Provider/AuthenticationRequestTest.cs
index 078ffb4..cb898be 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Provider/AuthenticationRequestTest.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Provider/AuthenticationRequestTest.cs
@@ -30,7 +30,7 @@ namespace DotNetOpenAuth.Test.OpenId.Provider {
// Now simulate the request being rejected and extract the user_setup_url
request.IsAuthenticated = false;
- Uri userSetupUrl = ((NegativeAssertionResponse)request.Response.OriginalMessage).UserSetupUrl;
+ Uri userSetupUrl = ((NegativeAssertionResponse)request.Response).UserSetupUrl;
Assert.IsNotNull(userSetupUrl);
// Now construct a new request as if it had just come in.
@@ -54,11 +54,11 @@ namespace DotNetOpenAuth.Test.OpenId.Provider {
checkIdRequest.Realm = RPRealmUri;
checkIdRequest.ReturnTo = RPUri;
AuthenticationRequest request = new AuthenticationRequest(provider, checkIdRequest);
- Assert.IsFalse(request.IsReturnUrlDiscoverable);
+ Assert.IsFalse(request.IsReturnUrlDiscoverable(this.MockResponder.MockWebRequestHandler));
this.MockResponder.RegisterMockRPDiscovery();
request = new AuthenticationRequest(provider, checkIdRequest);
- Assert.IsTrue(request.IsReturnUrlDiscoverable);
+ Assert.IsTrue(request.IsReturnUrlDiscoverable(this.MockResponder.MockWebRequestHandler));
}
}
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs b/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs
index 114a135..f1994d1 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs
@@ -96,7 +96,7 @@ namespace DotNetOpenAuth.Test.OpenId.Provider {
op => {
IRequest request = op.GetRequest();
Assert.IsInstanceOfType(request, typeof(AutoResponsiveRequest));
- request.Response.Send();
+ op.SendResponse(request);
});
coordinator.Run();
}
diff --git a/src/DotNetOpenAuth.TestWeb/OpenIdProviderEndpoint.ashx b/src/DotNetOpenAuth.TestWeb/OpenIdProviderEndpoint.ashx
index 1e618fd..b282a3b 100644
--- a/src/DotNetOpenAuth.TestWeb/OpenIdProviderEndpoint.ashx
+++ b/src/DotNetOpenAuth.TestWeb/OpenIdProviderEndpoint.ashx
@@ -13,7 +13,7 @@ public class OpenIdProviderEndpoint : IHttpHandler {
authRequest.IsAuthenticated = true;
}
- request.Response.Send();
+ provider.SendResponse(request);
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs
index fa89cf7..0a27f95 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs
@@ -93,49 +93,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
/// <summary>
- /// Gets a value indicating whether verification of the return URL claimed by the Relying Party
- /// succeeded.
- /// </summary>
- /// <remarks>
- /// Return URL verification is only attempted if this property is queried.
- /// The result of the verification is cached per request so calling this
- /// property getter multiple times in one request is not a performance hit.
- /// See OpenID Authentication 2.0 spec section 9.2.1.
- /// </remarks>
- public bool IsReturnUrlDiscoverable(IDirectWebRequestHandler requestHandler) {
- ErrorUtilities.VerifyArgumentNotNull(requestHandler, "requestHandler");
-
- ErrorUtilities.VerifyInternal(this.Realm != null, "Realm should have been read or derived by now.");
- try {
- foreach (var returnUrl in Realm.Discover(requestHandler, false)) {
- Realm discoveredReturnToUrl = returnUrl.ReturnToEndpoint;
-
- // The spec requires that the return_to URLs given in an RPs XRDS doc
- // do not contain wildcards.
- if (discoveredReturnToUrl.DomainWildcard) {
- Logger.WarnFormat("Realm {0} contained return_to URL {1} which contains a wildcard, which is not allowed.", Realm, discoveredReturnToUrl);
- continue;
- }
-
- // Use the same rules as return_to/realm matching to check whether this
- // URL fits the return_to URL we were given.
- if (discoveredReturnToUrl.Contains(this.RequestMessage.ReturnTo)) {
- // no need to keep looking after we find a match
- return true;
- }
- }
- } catch (ProtocolException ex) {
- // Don't do anything else. We quietly fail at return_to verification and return false.
- Logger.InfoFormat("Relying party discovery at URL {0} failed. {1}", Realm, ex);
- } catch (WebException ex) {
- // Don't do anything else. We quietly fail at return_to verification and return false.
- Logger.InfoFormat("Relying party discovery at URL {0} failed. {1}", Realm, ex);
- }
-
- return false;
- }
-
- /// <summary>
/// Gets a value indicating whether the Provider should help the user
/// select a Claimed Identifier to send back to the relying party.
/// </summary>
@@ -273,6 +230,53 @@ namespace DotNetOpenAuth.OpenId.Provider {
this.positiveResponse.ClaimedIdentifier = builder.Uri;
}
+ /// <summary>
+ /// Gets a value indicating whether verification of the return URL claimed by the Relying Party
+ /// succeeded.
+ /// </summary>
+ /// <param name="requestHandler">The request handler to use to perform relying party discovery.</param>
+ /// <returns>
+ /// <c>true</c> if the Relying Party passed discovery verification; <c>false</c> otherwise.
+ /// </returns>
+ /// <remarks>
+ /// Return URL verification is only attempted if this property is queried.
+ /// The result of the verification is cached per request so calling this
+ /// property getter multiple times in one request is not a performance hit.
+ /// See OpenID Authentication 2.0 spec section 9.2.1.
+ /// </remarks>
+ public bool IsReturnUrlDiscoverable(IDirectWebRequestHandler requestHandler) {
+ ErrorUtilities.VerifyArgumentNotNull(requestHandler, "requestHandler");
+
+ ErrorUtilities.VerifyInternal(this.Realm != null, "Realm should have been read or derived by now.");
+ try {
+ foreach (var returnUrl in Realm.Discover(requestHandler, false)) {
+ Realm discoveredReturnToUrl = returnUrl.ReturnToEndpoint;
+
+ // The spec requires that the return_to URLs given in an RPs XRDS doc
+ // do not contain wildcards.
+ if (discoveredReturnToUrl.DomainWildcard) {
+ Logger.WarnFormat("Realm {0} contained return_to URL {1} which contains a wildcard, which is not allowed.", Realm, discoveredReturnToUrl);
+ continue;
+ }
+
+ // Use the same rules as return_to/realm matching to check whether this
+ // URL fits the return_to URL we were given.
+ if (discoveredReturnToUrl.Contains(this.RequestMessage.ReturnTo)) {
+ // no need to keep looking after we find a match
+ return true;
+ }
+ }
+ } catch (ProtocolException ex) {
+ // Don't do anything else. We quietly fail at return_to verification and return false.
+ Logger.InfoFormat("Relying party discovery at URL {0} failed. {1}", Realm, ex);
+ } catch (WebException ex) {
+ // Don't do anything else. We quietly fail at return_to verification and return false.
+ Logger.InfoFormat("Relying party discovery at URL {0} failed. {1}", Realm, ex);
+ }
+
+ return false;
+ }
+
#endregion
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs
index b5e8c13..6c2c1c2 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs
@@ -43,7 +43,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="provider">The provider that received the request message.</param>
/// <param name="response">The response that is ready for transmittal.</param>
internal AutoResponsiveRequest(OpenIdProvider provider, IProtocolMessage response)
- : base(provider, IndirectResponseBase.GetVersion(response)) {
+ : base(IndirectResponseBase.GetVersion(response)) {
ErrorUtilities.VerifyArgumentNotNull(response, "response");
this.response = response;
diff --git a/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs
index f336827..b1ef269 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs
@@ -34,15 +34,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
Realm Realm { get; }
/// <summary>
- /// Attempts to perform relying party discovery of the return URL claimed by the Relying Party.
- /// </summary>
- /// <remarks>
- /// <para>Return URL verification is only attempted if this method is called.</para>
- /// <para>See OpenID Authentication 2.0 spec section 9.2.1.</para>
- /// </remarks>
- bool IsReturnUrlDiscoverable(IDirectWebRequestHandler requestHandler);
-
- /// <summary>
/// Gets a value indicating whether the Provider should help the user
/// select a Claimed Identifier to send back to the relying party.
/// </summary>
@@ -118,5 +109,18 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// request before the <see cref="ClaimedIdentifier"/> property is set.
/// </exception>
void SetClaimedIdentifierFragment(string fragment);
+
+ /// <summary>
+ /// Attempts to perform relying party discovery of the return URL claimed by the Relying Party.
+ /// </summary>
+ /// <param name="requestHandler">The request handler to use to perform relying party discovery.</param>
+ /// <returns>
+ /// <c>true</c> if the Relying Party passed discovery verification; <c>false</c> otherwise.
+ /// </returns>
+ /// <remarks>
+ /// <para>Return URL verification is only attempted if this method is called.</para>
+ /// <para>See OpenID Authentication 2.0 spec section 9.2.1.</para>
+ /// </remarks>
+ bool IsReturnUrlDiscoverable(IDirectWebRequestHandler requestHandler);
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs
index cf8fd99..022e9ae 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs
@@ -31,16 +31,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
bool IsResponseReady { get; }
/// <summary>
- /// Gets the response to send to the user agent.
- /// </summary>
- /// <remarks>
- /// The value of this property should be passed to <see cref="OpenIdProvider.PrepareResponse"/>
- /// or <see cref="Channel.PrepareResponse"/> to get the <see cref="UserAgentResponse"/> that
- /// can be transmitted to the remote party.
- /// </remarks>
- IProtocolMessage Response { get; }
-
- /// <summary>
/// Adds an extension to the response to send to the relying party.
/// </summary>
/// <param name="extension">The extension to add to the response message.</param>
diff --git a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
index f6b7790..7742137 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
using System;
using System.ComponentModel;
using System.Linq;
+ using System.Threading;
using System.Web;
using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
@@ -197,13 +198,30 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
/// <summary>
- /// Encodes a response message for transmission.
+ /// Sends the response to a received request.
/// </summary>
- /// <param name="responseMessage">The response message.</param>
- /// <returns>The serialized form of the message ready for transmission to the remote party.</returns>
- /// <remarks>This method merely delegates to <see cref="Channel.PrepareResponse"/>.</remarks>
- public UserAgentResponse PrepareResponse(IProtocolMessage responseMessage) {
- return this.Channel.PrepareResponse(responseMessage);
+ /// <param name="request">The incoming OpenID request whose response is to be sent.</param>
+ /// <exception cref="ThreadAbortException">Thrown by ASP.NET in order to prevent additional data from the page being sent to the client and corrupting the response.</exception>
+ /// <remarks>
+ /// <para>Requires an HttpContext.Current context. If one is not available, the caller should use
+ /// <see cref="GetResponse"/> instead and manually send the <see cref="UserAgentResponse"/>
+ /// to the client.</para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">Thrown if <see cref="IRequest.IsResponseReady"/> is <c>false</c>.</exception>
+ public void SendResponse(IRequest request) {
+ Request requestInternal = (Request)request;
+ this.Channel.Send(requestInternal.Response);
+ }
+
+ /// <summary>
+ /// Gets the response to a received request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>The response that should be sent to the client.</returns>
+ /// <exception cref="InvalidOperationException">Thrown if <see cref="IRequest.IsResponseReady"/> is <c>false</c>.</exception>
+ public UserAgentResponse GetResponse(IRequest request) {
+ Request requestInternal = (Request)request;
+ return this.Channel.PrepareResponse(requestInternal.Response);
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
index eef73e9..e5d0d74 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
@@ -13,6 +13,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetOpenAuth.Configuration;
+ using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Messages;
/// <summary>
@@ -22,7 +23,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
[DefaultEvent("AuthenticationChallenge")]
[ToolboxData("<{0}:ProviderEndpoint runat='server' />")]
- public class ProviderEndpoint : Control {
+ public class ProviderEndpoint : Control, IDisposable {
/// <summary>
/// The key used to store the pending authentication request in the ASP.NET session.
/// </summary>
@@ -39,6 +40,11 @@ namespace DotNetOpenAuth.OpenId.Provider {
private const string EnabledViewStateKey = "Enabled";
/// <summary>
+ /// Backing field for the <see cref="Provider"/> property.
+ /// </summary>
+ private static OpenIdProvider provider = CreateProvider();
+
+ /// <summary>
/// Fired when an incoming OpenID request is an authentication challenge
/// that must be responded to by the Provider web site according to its
/// own user database and policies.
@@ -46,6 +52,21 @@ namespace DotNetOpenAuth.OpenId.Provider {
public event EventHandler<AuthenticationChallengeEventArgs> AuthenticationChallenge;
/// <summary>
+ /// Gets or sets the <see cref="OpenIdProvider"/> instance to use for all instances of this control.
+ /// </summary>
+ /// <value>The default value is an <see cref="OpenIdProvider"/> instance initialized according to the web.config file.</value>
+ public static OpenIdProvider Provider {
+ get {
+ return provider;
+ }
+
+ set {
+ ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ provider = value;
+ }
+ }
+
+ /// <summary>
/// Gets or sets an incoming OpenID authentication request that has not yet been responded to.
/// </summary>
/// <remarks>
@@ -76,13 +97,12 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
/// <summary>
- /// Gets or sets a custom application store to use. Null to use the default.
+ /// Sends the response for the <see cref="PendingAuthenticationRequest"/> and clears the property.
/// </summary>
- /// <remarks>
- /// If set, this property must be set in each Page Load event
- /// as it is not persisted across postbacks.
- /// </remarks>
- public IProviderApplicationStore CustomApplicationStore { get; set; }
+ public static void SendResponse() {
+ Provider.SendResponse(PendingAuthenticationRequest);
+ PendingAuthenticationRequest = null;
+ }
/// <summary>
/// Checks for incoming OpenID requests, responds to ones it can
@@ -97,23 +117,21 @@ namespace DotNetOpenAuth.OpenId.Provider {
// Use the explicitly given state store on this control if there is one.
// Then try the configuration file specified one. Finally, use the default
// in-memory one that's built into OpenIdProvider.
- using (OpenIdProvider provider = new OpenIdProvider(this.CustomApplicationStore ?? DotNetOpenAuthSection.Configuration.OpenId.Provider.ApplicationStore.CreateInstance(OpenIdProvider.HttpApplicationStore))) {
- // determine what incoming message was received
- IRequest request = provider.GetRequest();
- if (request != null) {
- // process the incoming message appropriately and send the response
- if (!request.IsResponseReady) {
- var idrequest = (IAuthenticationRequest)request;
- PendingAuthenticationRequest = idrequest;
- this.OnAuthenticationChallenge(idrequest);
- } else {
- PendingAuthenticationRequest = null;
- }
- if (request.IsResponseReady) {
- request.Response.Send();
- Page.Response.End();
- PendingAuthenticationRequest = null;
- }
+ // determine what incoming message was received
+ IRequest request = provider.GetRequest();
+ if (request != null) {
+ // process the incoming message appropriately and send the response
+ if (!request.IsResponseReady) {
+ var idrequest = (IAuthenticationRequest)request;
+ PendingAuthenticationRequest = idrequest;
+ this.OnAuthenticationChallenge(idrequest);
+ } else {
+ PendingAuthenticationRequest = null;
+ }
+ if (request.IsResponseReady) {
+ provider.SendResponse(request);
+ Page.Response.End();
+ PendingAuthenticationRequest = null;
}
}
}
@@ -129,5 +147,13 @@ namespace DotNetOpenAuth.OpenId.Provider {
authenticationChallenge(this, new AuthenticationChallengeEventArgs(request));
}
}
+
+ /// <summary>
+ /// Creates the default OpenIdProvider to use.
+ /// </summary>
+ /// <returns>The new instance of OpenIdProvider.</returns>
+ private static OpenIdProvider CreateProvider() {
+ return new OpenIdProvider(DotNetOpenAuthSection.Configuration.OpenId.Provider.ApplicationStore.CreateInstance(OpenIdProvider.HttpApplicationStore));
+ }
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/Request.cs b/src/DotNetOpenAuth/OpenId/Provider/Request.cs
index 063be97..764e5b0 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/Request.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/Request.cs
@@ -70,7 +70,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <summary>
/// Gets the response to send to the user agent.
/// </summary>
- public IProtocolMessage Response {
+ /// <exception cref="InvalidOperationException">Thrown if <see cref="IsResponseReady"/> is <c>false</c>.</exception>
+ internal IProtocolMessage Response {
get {
ErrorUtilities.VerifyOperation(this.IsResponseReady, OpenIdStrings.ResponseNotReady);
if (this.responseExtensions.Count > 0) {