diff options
7 files changed, 88 insertions, 15 deletions
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs index ee08ed0..998c7eb 100644 --- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs @@ -120,10 +120,11 @@ namespace DotNetOpenAuth.Messaging { /// Strips any and all URI query parameters that start with some prefix. /// </summary> /// <param name="uri">The URI that may have a query with parameters to remove.</param> - /// <param name="prefix">The prefix for parameters to remove.</param> + /// <param name="prefix">The prefix for parameters to remove. A period is NOT automatically appended.</param> /// <returns>Either a new Uri with the parameters removed if there were any to remove, or the same Uri instance if no parameters needed to be removed.</returns> public static Uri StripQueryArgumentsWithPrefix(this Uri uri, string prefix) { ErrorUtilities.VerifyArgumentNotNull(uri, "uri"); + ErrorUtilities.VerifyNonZeroLength(prefix, "prefix"); NameValueCollection queryArgs = HttpUtility.ParseQueryString(uri.Query); var matchingKeys = queryArgs.Keys.OfType<string>().Where(key => key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)).ToList(); diff --git a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs index 6860abc..99e937e 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs @@ -23,7 +23,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { /// </summary> internal static readonly OpenIdExtensionFactory.CreateDelegate Factory = (typeUri, data, baseMessage) => { if (typeUri == Constants.sreg_ns && baseMessage is SignedResponseRequest) { - return new ClaimsRequest(); + return new ClaimsRequest(typeUri); } return null; diff --git a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs index d36cd8f..cca93a1 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs @@ -64,7 +64,7 @@ namespace DotNetOpenAuth.OpenId.Messages { ErrorUtilities.VerifyArgumentNotNull(request, "request"); this.ReturnTo = request.ReturnTo; - this.ProviderEndpoint = request.Recipient; + this.ProviderEndpoint = request.Recipient.StripQueryArgumentsWithPrefix(Protocol.openid.Prefix); ((ITamperResistantOpenIdMessage)this).AssociationHandle = request.AssociationHandle; } diff --git a/src/DotNetOpenAuth/OpenId/Messages/PositiveAssertionResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/PositiveAssertionResponse.cs index ed0516c..b167dc8 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/PositiveAssertionResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/PositiveAssertionResponse.cs @@ -48,6 +48,14 @@ namespace DotNetOpenAuth.OpenId.Messages { } /// <summary> + /// Initializes a new instance of the <see cref="PositiveAssertionResponse"/> class. + /// </summary> + /// <param name="relyingParty">The relying party return_to endpoint that will receive this positive assertion.</param> + internal PositiveAssertionResponse(RelyingPartyEndpointDescription relyingParty) + : this(relyingParty.Protocol.Version, relyingParty.ReturnToEndpoint) { + } + + /// <summary> /// Gets or sets the Claimed Identifier. /// </summary> /// <remarks> diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs index 8d9f04e..b0bdc6c 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs @@ -61,6 +61,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to An absolute URI is required for this value.. + /// </summary> + internal static string AbsoluteUriRequired { + get { + return ResourceManager.GetString("AbsoluteUriRequired", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to The requested association type '{0}' with session type '{1}' is unrecognized or not supported by this Provider due to security requirements.. /// </summary> internal static string AssociationOrSessionTypeUnrecognizedOrNotSupported { @@ -304,15 +313,6 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// Looks up a localized string similar to The value '{0}' is not a valid URI.. - /// </summary> - internal static string InvalidUri1 { - get { - return ResourceManager.GetString("InvalidUri1", resourceCulture); - } - } - - /// <summary> /// Looks up a localized string similar to Not a recognized XRI format: '{0}'.. /// </summary> internal static string InvalidXri { @@ -380,6 +380,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to No XRDS document containing OpenId relying party endpoint information could be found at {0}.. + /// </summary> + internal static string NoRelyingPartyEndpointDiscovered { + get { + return ResourceManager.GetString("NoRelyingPartyEndpointDiscovered", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to Diffie-Hellman session type '{0}' not found for OpenID {1}.. /// </summary> internal static string NoSessionTypeFound { diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx index 43133db..6e88fcc 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx +++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx @@ -253,9 +253,6 @@ Discovered endpoint info: <data name="AttributeTooManyValues" xml:space="preserve"> <value>Only {0} values for attribute '{1}' were requested, but {2} were supplied.</value> </data> - <data name="InvalidUri1" xml:space="preserve"> - <value>The value '{0}' is not a valid URI.</value> - </data> <data name="UnspecifiedDateTimeKindNotAllowed" xml:space="preserve"> <value>Providing a DateTime whose Kind is Unspecified is not allowed.</value> </data> @@ -283,4 +280,10 @@ Discovered endpoint info: <data name="NotSupportedByAuthenticationSnapshot" xml:space="preserve"> <value>This operation is not supported by serialized authentication responses. Try this operation from the LoggedIn event handler.</value> </data> + <data name="NoRelyingPartyEndpointDiscovered" xml:space="preserve"> + <value>No XRDS document containing OpenId relying party endpoint information could be found at {0}.</value> + </data> + <data name="AbsoluteUriRequired" xml:space="preserve"> + <value>An absolute URI is required for this value.</value> + </data> </root>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs index 2ebf6d2..8aca2ab 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OpenId.Provider { using System; using System.ComponentModel; + using System.Linq; using System.Web; using DotNetOpenAuth.Configuration; using DotNetOpenAuth.Messaging; @@ -170,5 +171,56 @@ namespace DotNetOpenAuth.OpenId.Provider { throw ErrorUtilities.ThrowProtocol(MessagingStrings.UnexpectedMessageReceivedOfMany); } + + /// <summary> + /// Send an identity assertion on behalf of one of this Provider's + /// members in order to redirect the user agent to a relying party + /// web site and log him/her in immediately in one uninterrupted step. + /// </summary> + /// <param name="providerEndpoint">The absolute URL on the Provider site that receives OpenID messages.</param> + /// <param name="relyingParty">The URL of the Relying Party web site. + /// This will typically be the home page, but may be a longer URL if + /// that Relying Party considers the scope of its realm to be more specific. + /// The URL provided here must allow discovery of the Relying Party's + /// XRDS document that advertises its OpenID RP endpoint.</param> + /// <param name="claimedIdentifier">The Identifier you are asserting your member controls.</param> + /// <param name="localIdentifier">The Identifier you know your user by internally. This will typically + /// be the same as <paramref name="claimedIdentifier"/>.</param> + /// <param name="extensions">The extensions.</param> + /// <returns> + /// A <see cref="UserAgentResponse"/> object describing the HTTP response to send + /// the user agent to allow the redirect with assertion to happen. + /// </returns> + public UserAgentResponse PrepareUnsolicitedAssertion(Uri providerEndpoint, Realm relyingParty, Identifier claimedIdentifier, Identifier localIdentifier, params IExtensionMessage[] extensions) { + ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint"); + ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty"); + ErrorUtilities.VerifyArgumentNotNull(claimedIdentifier, "claimedIdentifier"); + ErrorUtilities.VerifyArgumentNotNull(localIdentifier, "localIdentifier"); + ErrorUtilities.VerifyArgumentNamed(providerEndpoint.IsAbsoluteUri, "providerEndpoint", OpenIdStrings.AbsoluteUriRequired); + + // Although the RP should do their due diligence to make sure that this OP + // is authorized to send an assertion for the given claimed identifier, + // do due diligence by performing our own discovery on the claimed identifier + // and make sure that it is tied to this OP and OP local identifier. + // TODO: code here + + Logger.InfoFormat("Preparing unsolicited assertion for {0}", claimedIdentifier); + var returnToEndpoint = relyingParty.Discover(this.WebRequestHandler, true).FirstOrDefault(); + ErrorUtilities.VerifyProtocol(returnToEndpoint != null, OpenIdStrings.NoRelyingPartyEndpointDiscovered, relyingParty); + + var positiveAssertion = new PositiveAssertionResponse(returnToEndpoint) { + ProviderEndpoint = providerEndpoint, + ClaimedIdentifier = claimedIdentifier, + LocalIdentifier = localIdentifier, + }; + + if (extensions != null) { + foreach (IExtensionMessage extension in extensions) { + positiveAssertion.Extensions.Add(extension); + } + } + + return this.Channel.PrepareResponse(positiveAssertion); + } } } |