diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-07-27 20:31:42 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-07-27 20:31:42 -0700 |
commit | 9abf0d6c972d7e26233522ec4fc1f5cc80799202 (patch) | |
tree | ae6f0b423563a53a368809b14d2e158b23cab87b | |
parent | fd0ffe71d4d861b9a76df8090eacd9208c1c3053 (diff) | |
parent | e6849bb0cefdddcaa9002aaeac7a21f76e7f4e4c (diff) | |
download | DotNetOpenAuth-9abf0d6c972d7e26233522ec4fc1f5cc80799202.zip DotNetOpenAuth-9abf0d6c972d7e26233522ec4fc1f5cc80799202.tar.gz DotNetOpenAuth-9abf0d6c972d7e26233522ec4fc1f5cc80799202.tar.bz2 |
Merge branch 'v3.0' into v3.1
Conflicts:
src/version.txt
26 files changed, 100 insertions, 10 deletions
diff --git a/samples/OpenIdProviderMvc/Web.config b/samples/OpenIdProviderMvc/Web.config index 7b078ef..029414a 100644 --- a/samples/OpenIdProviderMvc/Web.config +++ b/samples/OpenIdProviderMvc/Web.config @@ -188,4 +188,8 @@ <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </handlers> </system.webServer> + + <runtime> + <legacyHMACWarning enabled="0" /> + </runtime> </configuration> diff --git a/samples/OpenIdProviderWebForms/Web.config b/samples/OpenIdProviderWebForms/Web.config index 7626751..745cb2c 100644 --- a/samples/OpenIdProviderWebForms/Web.config +++ b/samples/OpenIdProviderWebForms/Web.config @@ -176,6 +176,7 @@ </handlers> </system.webServer> <runtime> + <legacyHMACWarning enabled="0" /> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/> diff --git a/samples/OpenIdRelyingPartyMvc/Web.config b/samples/OpenIdRelyingPartyMvc/Web.config index ba97122..bb9f8e1 100644 --- a/samples/OpenIdRelyingPartyMvc/Web.config +++ b/samples/OpenIdRelyingPartyMvc/Web.config @@ -167,4 +167,8 @@ <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </handlers> </system.webServer> + + <runtime> + <legacyHMACWarning enabled="0" /> + </runtime> </configuration> diff --git a/samples/OpenIdRelyingPartyWebForms/Web.config b/samples/OpenIdRelyingPartyWebForms/Web.config index 2a13828..4408ebf 100644 --- a/samples/OpenIdRelyingPartyWebForms/Web.config +++ b/samples/OpenIdRelyingPartyWebForms/Web.config @@ -97,4 +97,7 @@ </logger> </log4net> + <runtime> + <legacyHMACWarning enabled="0" /> + </runtime> </configuration> diff --git a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx index df29914..232cf3f 100644 --- a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx +++ b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx @@ -3,6 +3,10 @@ <%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="openid" %> <asp:Content runat="server" ContentPlaceHolderID="head"> +<script> +// window.openid_visible_iframe = true; // causes the hidden iframe to show up +// window.openid_trace = true; // causes lots of messages +</script> <style type="text/css"> .textbox { diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs index 7701090..083b988 100644 --- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs @@ -59,6 +59,18 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { Assert.AreEqual(AuthenticationStatus.Failed, authResponse.Status); } + /// <summary> + /// Verifies that the RP rejects positive assertions with HTTP Claimed + /// Cdentifiers when RequireSsl is set to true. + /// </summary> + [TestMethod, ExpectedException(typeof(ProtocolException))] + public void InsecureIdentifiersRejectedWithRequireSsl() { + PositiveAssertionResponse assertion = this.GetPositiveAssertion(); + var rp = CreateRelyingParty(); + rp.SecuritySettings.RequireSsl = true; + var authResponse = new PositiveAuthenticationResponse(assertion, rp); + } + [TestMethod] public void GetCallbackArguments() { PositiveAssertionResponse assertion = this.GetPositiveAssertion(); diff --git a/src/DotNetOpenAuth/Configuration/OAuthConsumerSecuritySettingsElement.cs b/src/DotNetOpenAuth/Configuration/OAuthConsumerSecuritySettingsElement.cs index 5e75390..38a183a 100644 --- a/src/DotNetOpenAuth/Configuration/OAuthConsumerSecuritySettingsElement.cs +++ b/src/DotNetOpenAuth/Configuration/OAuthConsumerSecuritySettingsElement.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Configuration { using System; using System.Collections.Generic; using System.Configuration; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using DotNetOpenAuth.OAuth; @@ -26,6 +27,7 @@ namespace DotNetOpenAuth.Configuration { /// Initializes a programmatically manipulatable bag of these security settings with the settings from the config file. /// </summary> /// <returns>The newly created security settings object.</returns> + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "By design")] internal ConsumerSecuritySettings CreateSecuritySettings() { return new ConsumerSecuritySettings(); } diff --git a/src/DotNetOpenAuth/GlobalSuppressions.cs b/src/DotNetOpenAuth/GlobalSuppressions.cs index 842e6dd..6997632 100644 --- a/src/DotNetOpenAuth/GlobalSuppressions.cs +++ b/src/DotNetOpenAuth/GlobalSuppressions.cs @@ -42,3 +42,4 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "We sign it when producing drops.")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.OAuth")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.Messaging.Reflection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "oauthverifier", Scope = "resource", Target = "DotNetOpenAuth.OAuth.OAuthStrings.resources")] diff --git a/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs b/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs index 1d4d28e..3d624a6 100644 --- a/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs +++ b/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs @@ -73,7 +73,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// <see cref="StandardExpirationBindingElement.MaximumMessageAge"/> property. /// </remarks> public bool StoreNonce(string context, string nonce, DateTime timestamp) { - if (timestamp.ToUniversalTime() + this.maximumMessageAge < DateTime.UtcNow) { + if (timestamp.ToUniversalTimeSafe() + this.maximumMessageAge < DateTime.UtcNow) { // The expiration binding element should have taken care of this, but perhaps // it's at the boundary case. We should fail just to be safe. return false; @@ -115,7 +115,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// </summary> public void ClearExpiredNonces() { lock (this.nonceLock) { - var oldNonceLists = this.usedNonces.Keys.Where(time => time.ToUniversalTime() + this.maximumMessageAge < DateTime.UtcNow).ToList(); + var oldNonceLists = this.usedNonces.Keys.Where(time => time.ToUniversalTimeSafe() + this.maximumMessageAge < DateTime.UtcNow).ToList(); foreach (DateTime time in oldNonceLists) { this.usedNonces.Remove(time); } diff --git a/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs b/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs index 5fcf4bd..7b00e34 100644 --- a/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs +++ b/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs @@ -87,7 +87,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { if (expiringMessage != null) { // Yes the UtcCreationDate is supposed to always be in UTC already, // but just in case a given message failed to guarantee that, we do it here. - DateTime expirationDate = expiringMessage.UtcCreationDate.ToUniversalTime() + MaximumMessageAge; + DateTime expirationDate = expiringMessage.UtcCreationDate.ToUniversalTimeSafe() + MaximumMessageAge; if (expirationDate < DateTime.UtcNow) { throw new ExpiredMessageException(expirationDate, expiringMessage); } diff --git a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs index e532e99..79a1107 100644 --- a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs +++ b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs @@ -12,6 +12,7 @@ namespace DotNetOpenAuth.Messaging { /// An immutable description of a URL that receives messages. /// </summary> [DebuggerDisplay("{AllowedMethods} {Location}")] + [Serializable] public class MessageReceivingEndpoint { /// <summary> /// Initializes a new instance of the <see cref="MessageReceivingEndpoint"/> class. diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs index da95771..463b556 100644 --- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs @@ -765,6 +765,32 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> + /// Ensures that UTC times are converted to local times. Unspecified kinds are unchanged. + /// </summary> + /// <param name="value">The date-time to convert.</param> + /// <returns>The date-time in local time.</returns> + internal static DateTime ToLocalTimeSafe(this DateTime value) { + if (value.Kind == DateTimeKind.Unspecified) { + return value; + } + + return value.ToLocalTime(); + } + + /// <summary> + /// Ensures that local times are converted to UTC times. Unspecified kinds are unchanged. + /// </summary> + /// <param name="value">The date-time to convert.</param> + /// <returns>The date-time in UTC time.</returns> + internal static DateTime ToUniversalTimeSafe(this DateTime value) { + if (value.Kind == DateTimeKind.Unspecified) { + return value; + } + + return value.ToUniversalTime(); + } + + /// <summary> /// A class to convert a <see cref="Comparison<T>"/> into an <see cref="IComparer<T>"/>. /// </summary> /// <typeparam name="T">The type of objects being compared.</typeparam> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs index 123582a..a1939dd 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs @@ -307,7 +307,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <para>This method implements OAuth 1.0 section 5.2, item #1 (described in section 5.4).</para> /// </remarks> private HttpWebRequest InitializeRequestAsAuthHeader(IDirectedProtocolMessage requestMessage) { - var protocol = Protocol.Lookup(requestMessage.Version); var dictionary = this.MessageDescriptions.GetAccessor(requestMessage); // copy so as to not modify original diff --git a/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs b/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs index 89e0276..944bc5c 100644 --- a/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs +++ b/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs @@ -17,6 +17,7 @@ namespace DotNetOpenAuth.OAuth.Messages { /// <summary> /// A base class for all OAuth messages. /// </summary> + [Serializable] public abstract class MessageBase : IDirectedProtocolMessage, IDirectResponseProtocolMessage { /// <summary> /// A store for extra name/value data pairs that are attached to this message. diff --git a/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs b/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs index 8ccd8e3..ce09213 100644 --- a/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs +++ b/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs @@ -89,6 +89,8 @@ namespace DotNetOpenAuth.OAuth.Messages { /// <summary> /// Gets a value indicating whether the Service Provider recognized the callback parameter in the request. /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Message serialization invoked.")] + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Message parts must be instance members.")] [MessagePart("oauth_callback_confirmed", IsRequired = true, MinVersion = Protocol.V10aVersion)] private bool CallbackConfirmed { get { return true; } diff --git a/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationRequest.cs b/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationRequest.cs index 099729e..a5823bb 100644 --- a/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationRequest.cs +++ b/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationRequest.cs @@ -15,6 +15,7 @@ namespace DotNetOpenAuth.OAuth.Messages { /// so the Service Provider can ask the user to authorize the Consumer's access to some /// protected resource(s). /// </summary> + [Serializable] public class UserAuthorizationRequest : MessageBase, ITokenContainingMessage { /// <summary> /// Initializes a new instance of the <see cref="UserAuthorizationRequest"/> class. diff --git a/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationResponse.cs b/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationResponse.cs index 69a327c..73fddc7 100644 --- a/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationResponse.cs +++ b/src/DotNetOpenAuth/OAuth/Messages/UserAuthorizationResponse.cs @@ -14,6 +14,7 @@ namespace DotNetOpenAuth.OAuth.Messages { /// <remarks> /// The class is sealed because extra parameters are determined by the callback URI provided by the Consumer. /// </remarks> + [Serializable] public sealed class UserAuthorizationResponse : MessageBase, ITokenContainingMessage { /// <summary> /// Initializes a new instance of the <see cref="UserAuthorizationResponse"/> class. diff --git a/src/DotNetOpenAuth/OAuth/Protocol.cs b/src/DotNetOpenAuth/OAuth/Protocol.cs index f535b10..cd4e486 100644 --- a/src/DotNetOpenAuth/OAuth/Protocol.cs +++ b/src/DotNetOpenAuth/OAuth/Protocol.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OAuth { using System; using System.Collections.Generic; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; @@ -24,6 +25,7 @@ namespace DotNetOpenAuth.OAuth { /// <summary> /// OAuth 1.0a specification /// </summary> + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "a", Justification = "By design.")] V10a, } diff --git a/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs b/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs index d25c988..3afd44e 100644 --- a/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs +++ b/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs @@ -5,6 +5,8 @@ //----------------------------------------------------------------------- namespace DotNetOpenAuth.OAuth { + using System.Diagnostics.CodeAnalysis; + /// <summary> /// The different formats a user authorization verifier code can take /// in order to be as secure as possible while being compatible with @@ -33,6 +35,8 @@ namespace DotNetOpenAuth.OAuth { /// Some letters and numbers will be skipped where they are visually similar /// enough that they can be difficult to distinguish when displayed with most fonts. /// </remarks> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Alikes", Justification = "Breaking change of existing API")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "AlphaNumeric", Justification = "Breaking change of existing API")] AlphaNumericNoLookAlikes, /// <summary> diff --git a/src/DotNetOpenAuth/OpenId/Association.cs b/src/DotNetOpenAuth/OpenId/Association.cs index eb7c880..ce129bb 100644 --- a/src/DotNetOpenAuth/OpenId/Association.cs +++ b/src/DotNetOpenAuth/OpenId/Association.cs @@ -149,7 +149,7 @@ namespace DotNetOpenAuth.OpenId { if (privateData == null) { throw new ArgumentNullException("privateData"); } - expires = expires.ToUniversalTime(); + expires = expires.ToUniversalTimeSafe(); TimeSpan remainingLifeLength = expires - DateTime.UtcNow; byte[] secret = privateData; // the whole of privateData is the secret key for now. // We figure out what derived type to instantiate based on the length of the secret. diff --git a/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/DateTimeEncoder.cs b/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/DateTimeEncoder.cs index 82297d0..9dc0574 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/DateTimeEncoder.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/DateTimeEncoder.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy { using System; using System.Globalization; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; /// <summary> @@ -39,7 +40,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy { public string Encode(object value) { DateTime? dateTime = value as DateTime?; if (dateTime.HasValue) { - return dateTime.Value.ToUniversalTime().ToString(PermissibleDateTimeFormats[0], CultureInfo.InvariantCulture); + return dateTime.Value.ToUniversalTimeSafe().ToString(PermissibleDateTimeFormats[0], CultureInfo.InvariantCulture); } else { return null; } diff --git a/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs b/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs index 4b2bcc9..b476cf7 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs @@ -90,7 +90,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy { // Convert to UTC and cut to the second, since the protocol only allows for // that level of precision. - this.authenticationTimeUtc = OpenIdUtilities.CutToSecond(value.Value.ToUniversalTime()); + this.authenticationTimeUtc = OpenIdUtilities.CutToSecond(value.Value.ToUniversalTimeSafe()); } else { this.authenticationTimeUtc = null; } diff --git a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs index 0d105ad..9462d21 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs @@ -201,7 +201,7 @@ namespace DotNetOpenAuth.OpenId.Messages { /// </exception> DateTime IExpiringProtocolMessage.UtcCreationDate { get { return this.creationDateUtc; } - set { this.creationDateUtc = value.ToUniversalTime(); } + set { this.creationDateUtc = value.ToUniversalTimeSafe(); } } /// <summary> diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs index a6e02fe..fb6e997 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs @@ -470,6 +470,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to Sorry. This site only accepts OpenIDs that are HTTPS-secured, but {0} is not a secure Identifier.. + /// </summary> + internal static string RequireSslNotSatisfiedByAssertedClaimedId { + get { + return ResourceManager.GetString("RequireSslNotSatisfiedByAssertedClaimedId", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to The response is not ready. Use IsResponseReady to check whether a response is ready first.. /// </summary> internal static string ResponseNotReady { diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx index 95fe655..20d3b67 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx +++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx @@ -301,4 +301,7 @@ Discovered endpoint info: <data name="UnsupportedChannelConfiguration" xml:space="preserve"> <value>This feature is unavailable due to an unrecognized channel configuration.</value> </data> -</root>
\ No newline at end of file + <data name="RequireSslNotSatisfiedByAssertedClaimedId" xml:space="preserve"> + <value>Sorry. This site only accepts OpenIDs that are HTTPS-secured, but {0} is not a secure Identifier.</value> + </data> +</root> diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs index 32980f5..a7cf801 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs @@ -316,6 +316,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { private void VerifyDiscoveryMatchesAssertion() { Logger.OpenId.Debug("Verifying assertion matches identifier discovery results..."); + // Ensure that we abide by the RP's rules regarding RequireSsl for this discovery step. + Identifier claimedId = this.Response.ClaimedIdentifier; + if (this.relyingParty.SecuritySettings.RequireSsl) { + if (!claimedId.TryRequireSsl(out claimedId)) { + Logger.OpenId.ErrorFormat("This site is configured to accept only SSL-protected OpenIDs, but {0} was asserted and must be rejected.", this.Response.ClaimedIdentifier); + ErrorUtilities.ThrowProtocol(OpenIdStrings.RequireSslNotSatisfiedByAssertedClaimedId, this.Response.ClaimedIdentifier); + } + } + // While it LOOKS like we're performing discovery over HTTP again // Yadis.IdentifierDiscoveryCachePolicy is set to HttpRequestCacheLevel.CacheIfAvailable // which means that the .NET runtime is caching our discoveries for us. This turns out @@ -325,7 +334,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { // is signed by the RP before it's considered reliable. In 1.x stateless mode, this RP // doesn't (and can't) sign its own return_to URL, so its cached discovery information // is merely a hint that must be verified by performing discovery again here. - var discoveryResults = this.response.ClaimedIdentifier.Discover(this.relyingParty.WebRequestHandler); + var discoveryResults = claimedId.Discover(this.relyingParty.WebRequestHandler); ErrorUtilities.VerifyProtocol(discoveryResults.Contains(this.endpoint), OpenIdStrings.IssuedAssertionFailsIdentifierDiscovery, this.endpoint, discoveryResults.ToStringDeferred(true)); } } |