diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-03-06 14:55:50 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-03-06 15:01:02 -0800 |
commit | 58669d51de6db631c3b56a53e4a7aa5a384e5fec (patch) | |
tree | 25c1688096a20b9b2094ec1fd11697ae651b30d8 | |
parent | 83384150efcda894097e9e2a4448994361b8a626 (diff) | |
download | DotNetOpenAuth-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.
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) { |