summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-11-02 17:24:06 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2009-11-02 17:24:06 -0800
commitb1cbd4b7a27a9fa02c9a99225336e609a7df5e86 (patch)
tree9ee0eae3ee45fb524091b3f1e687e5229bd68f2d /src
parent716524c4b800c06aa033c53af991151f70851b89 (diff)
downloadDotNetOpenAuth-b1cbd4b7a27a9fa02c9a99225336e609a7df5e86.zip
DotNetOpenAuth-b1cbd4b7a27a9fa02c9a99225336e609a7df5e86.tar.gz
DotNetOpenAuth-b1cbd4b7a27a9fa02c9a99225336e609a7df5e86.tar.bz2
OPs can now opt out of verifying identifiers they are sending unsolicited assertions for.
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd9
-rw-r--r--src/DotNetOpenAuth/Configuration/OpenIdProviderSecuritySettingsElement.cs17
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs26
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs44
4 files changed, 86 insertions, 10 deletions
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
index ea32f4c..a214053 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
@@ -197,6 +197,15 @@
</xs:choice>
<xs:attribute name="requireSsl" type="xs:boolean" default="false" />
<xs:attribute name="protectDownlevelReplayAttacks" type="xs:boolean" />
+ <xs:attribute name="unsolicitedAssertionVerification">
+ <xs:simpleType>
+ <xs:restriction base="xs:NMTOKEN">
+ <xs:enumeration value="RequireSuccess" />
+ <xs:enumeration value="LogWarningOnFailure" />
+ <xs:enumeration value="NeverVerify" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
<xs:attribute name="minimumHashBitLength" type="xs:int" />
<xs:attribute name="maximumHashBitLength" type="xs:int" />
</xs:complexType>
diff --git a/src/DotNetOpenAuth/Configuration/OpenIdProviderSecuritySettingsElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdProviderSecuritySettingsElement.cs
index 457955c..cd927f2 100644
--- a/src/DotNetOpenAuth/Configuration/OpenIdProviderSecuritySettingsElement.cs
+++ b/src/DotNetOpenAuth/Configuration/OpenIdProviderSecuritySettingsElement.cs
@@ -41,6 +41,11 @@ namespace DotNetOpenAuth.Configuration {
private const string RequireSslConfigName = "requireSsl";
/// <summary>
+ /// Gets the name of the @unsolicitedAssertionVerification attribute.
+ /// </summary>
+ private const string UnsolicitedAssertionVerificationConfigName = "unsolicitedAssertionVerification";
+
+ /// <summary>
/// Initializes a new instance of the <see cref="OpenIdProviderSecuritySettingsElement"/> class.
/// </summary>
public OpenIdProviderSecuritySettingsElement() {
@@ -84,6 +89,17 @@ namespace DotNetOpenAuth.Configuration {
}
/// <summary>
+ /// Gets or sets the level of verification a Provider performs on an identifier before
+ /// sending an unsolicited assertion for it.
+ /// </summary>
+ /// <value>The default value is <see cref="UnsolicitedAssertionVerificationLevel.Always"/>.</value>
+ [ConfigurationProperty(UnsolicitedAssertionVerificationConfigName, DefaultValue = ProviderSecuritySettings.UnsolicitedAssertionVerificationDefault)]
+ public ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel UnsolicitedAssertionVerification {
+ get { return (ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel)this[UnsolicitedAssertionVerificationConfigName]; }
+ set { this[UnsolicitedAssertionVerificationConfigName] = value; }
+ }
+
+ /// <summary>
/// Gets or sets the configured lifetimes of the various association types.
/// </summary>
[ConfigurationProperty(AssociationsConfigName, IsDefaultCollection = false)]
@@ -109,6 +125,7 @@ namespace DotNetOpenAuth.Configuration {
settings.MinimumHashBitLength = this.MinimumHashBitLength;
settings.MaximumHashBitLength = this.MaximumHashBitLength;
settings.ProtectDownlevelReplayAttacks = this.ProtectDownlevelReplayAttacks;
+ settings.UnsolicitedAssertionVerification = this.UnsolicitedAssertionVerification;
foreach (AssociationTypeElement element in this.AssociationLifetimes) {
Contract.Assume(element != null);
settings.AssociationLifetimes.Add(element.AssociationType, element.MaximumLifetime);
diff --git a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
index e964506..b6de509 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
@@ -373,16 +373,22 @@ namespace DotNetOpenAuth.OpenId.Provider {
// 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.
- var serviceEndpoint = DotNetOpenAuth.OpenId.RelyingParty.ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, localIdentifier, new ProviderEndpointDescription(providerEndpoint, Protocol.Default.Version), null, null);
- var discoveredEndpoints = claimedIdentifier.Discover(this.WebRequestHandler);
- if (!discoveredEndpoints.Contains(serviceEndpoint)) {
- Logger.OpenId.DebugFormat(
- "Failed to send unsolicited assertion for {0} because its discovered services did not include this endpoint: {1}{2}{1}Discovered endpoints: {1}{3}",
- claimedIdentifier,
- Environment.NewLine,
- serviceEndpoint,
- discoveredEndpoints.ToStringDeferred(true));
- ErrorUtilities.ThrowProtocol(OpenIdStrings.UnsolicitedAssertionForUnrelatedClaimedIdentifier, claimedIdentifier);
+ if (this.SecuritySettings.UnsolicitedAssertionVerification != ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel.NeverVerify) {
+ var serviceEndpoint = DotNetOpenAuth.OpenId.RelyingParty.ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, localIdentifier, new ProviderEndpointDescription(providerEndpoint, Protocol.Default.Version), null, null);
+ var discoveredEndpoints = claimedIdentifier.Discover(this.WebRequestHandler);
+ if (!discoveredEndpoints.Contains(serviceEndpoint)) {
+ Logger.OpenId.WarnFormat(
+ "Failed to send unsolicited assertion for {0} because its discovered services did not include this endpoint: {1}{2}{1}Discovered endpoints: {1}{3}",
+ claimedIdentifier,
+ Environment.NewLine,
+ serviceEndpoint,
+ discoveredEndpoints.ToStringDeferred(true));
+
+ // Only FAIL if the setting is set for it.
+ if (this.securitySettings.UnsolicitedAssertionVerification == ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel.RequireSuccess) {
+ ErrorUtilities.ThrowProtocol(OpenIdStrings.UnsolicitedAssertionForUnrelatedClaimedIdentifier, claimedIdentifier);
+ }
+ }
}
Logger.OpenId.InfoFormat("Preparing unsolicited assertion for {0}", claimedIdentifier);
diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs
index 876e412..ddc10d2 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs
@@ -28,6 +28,11 @@ namespace DotNetOpenAuth.OpenId.Provider {
internal const bool SignOutgoingExtensionsDefault = true;
/// <summary>
+ /// The default value for the <see cref="UnsolicitedAssertionVerification"/> property.
+ /// </summary>
+ internal const UnsolicitedAssertionVerificationLevel UnsolicitedAssertionVerificationDefault = UnsolicitedAssertionVerificationLevel.RequireSuccess;
+
+ /// <summary>
/// The subset of association types and their customized lifetimes.
/// </summary>
private IDictionary<string, TimeSpan> associationLifetimes = new Dictionary<string, TimeSpan>();
@@ -39,6 +44,37 @@ namespace DotNetOpenAuth.OpenId.Provider {
: base(true) {
this.SignOutgoingExtensions = SignOutgoingExtensionsDefault;
this.ProtectDownlevelReplayAttacks = ProtectDownlevelReplayAttacksDefault;
+ this.UnsolicitedAssertionVerification = UnsolicitedAssertionVerificationDefault;
+ }
+
+ /// <summary>
+ /// The behavior a Provider takes when verifying that it is authoritative for an
+ /// identifier it is about to send an unsolicited assertion for.
+ /// </summary>
+ public enum UnsolicitedAssertionVerificationLevel {
+ /// <summary>
+ /// Always verify that the Provider is authoritative for an identifier before
+ /// sending an unsolicited assertion for it and fail if it is not.
+ /// </summary>
+ RequireSuccess,
+
+ /// <summary>
+ /// Always check that the Provider is authoritative for an identifier before
+ /// sending an unsolicited assertion for it, but only log failures, and proceed
+ /// to send the unsolicited assertion.
+ /// </summary>
+ LogWarningOnFailure,
+
+ /// <summary>
+ /// Never verify that the Provider is authoritative for an identifier before
+ /// sending an unsolicited assertion for it.
+ /// </summary>
+ /// <remarks>
+ /// This setting is useful for web servers that refuse to allow a Provider to
+ /// introspectively perform an HTTP GET on itself, when sending unsolicited assertions
+ /// for identifiers that the OP controls.
+ /// </remarks>
+ NeverVerify,
}
/// <summary>
@@ -57,6 +93,13 @@ namespace DotNetOpenAuth.OpenId.Provider {
public bool RequireSsl { get; set; }
/// <summary>
+ /// Gets or sets the level of verification a Provider performs on an identifier before
+ /// sending an unsolicited assertion for it.
+ /// </summary>
+ /// <value>The default value is <see cref="UnsolicitedAssertionVerificationLevel.Always"/>.</value>
+ public UnsolicitedAssertionVerificationLevel UnsolicitedAssertionVerification { get; set; }
+
+ /// <summary>
/// Gets or sets a value indicating whether OpenID 1.x relying parties that may not be
/// protecting their users from replay attacks are protected from
/// replay attacks by this provider.
@@ -101,6 +144,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
securitySettings.ProtectDownlevelReplayAttacks = this.ProtectDownlevelReplayAttacks;
securitySettings.RequireSsl = this.RequireSsl;
securitySettings.SignOutgoingExtensions = this.SignOutgoingExtensions;
+ securitySettings.UnsolicitedAssertionVerification = this.UnsolicitedAssertionVerification;
return securitySettings;
}