summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Web.config6
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd60
-rw-r--r--src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs21
-rw-r--r--src/DotNetOpenAuth/Configuration/TrustedProviderConfigurationCollection.cs71
-rw-r--r--src/DotNetOpenAuth/Configuration/TrustedProviderEndpointConfigurationElement.cs63
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj2
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs41
7 files changed, 259 insertions, 5 deletions
diff --git a/samples/OpenIdRelyingPartyWebForms/Web.config b/samples/OpenIdRelyingPartyWebForms/Web.config
index 5d3a33b..497af21 100644
--- a/samples/OpenIdRelyingPartyWebForms/Web.config
+++ b/samples/OpenIdRelyingPartyWebForms/Web.config
@@ -28,7 +28,11 @@
<dotNetOpenAuth>
<openid>
<relyingParty>
- <security requireSsl="false" />
+ <security requireSsl="false">
+ <trustedProviders rejectAssertionsFromUntrustedProviders="true">
+ <add endpoint="https://www.google.com/accounts/o8/ud" allowSubPath="true" allowAdditionalQueryParameters="true" />
+ </trustedProviders>
+ </security>
<behaviors>
<!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
with OPs that use Attribute Exchange (in various formats). -->
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
index 9c0ab77..3774490 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
@@ -243,6 +243,58 @@
</xs:documentation>
</xs:annotation>
<xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="trustedProviders">
+ <xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="add">
+ <xs:complexType>
+ <xs:attribute name="endpoint" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The OpenID Provider Endpoint (aka "OP Endpoint") that this relying party trusts.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="allowSubPath" type="xs:boolean" default="false">
+ <xs:annotation>
+ <xs:documentation>
+ A value indicating whether the OP Endpoint given here is a base path, and sub-paths concatenated to it are equally trusted.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="allowAdditionalQueryParameters" type="xs:boolean" default="false">
+ <xs:annotation>
+ <xs:documentation>
+ A value indicating whether the OP Endpoint given here is equally trusted if query string parameters are added to it.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="remove">
+ <xs:complexType>
+ <xs:attribute name="endpoint" type="xs:string" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="clear">
+ <xs:complexType>
+ <!--tag is empty-->
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ <xs:attribute name="rejectAssertionsFromUntrustedProviders" type="xs:boolean" default="false">
+ <xs:annotation>
+ <xs:documentation>
+ A value indicating whether any login attempt coming from an OpenID Provider Endpoint that is not on this
+ whitelist of trusted OP Endpoints will be rejected. If the trusted providers list is empty and this value
+ is true, all assertions are rejected.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
<xs:attribute name="requireSsl" type="xs:boolean" default="false">
<xs:annotation>
<xs:documentation>
@@ -269,7 +321,7 @@
<xs:attribute name="minimumHashBitLength" type="xs:int">
<xs:annotation>
<xs:documentation>
- Shared associations with OpenID Providers will only be formed or used if they
+ Shared associations with OpenID Providers will only be formed or used if they
are willing to form associations equal to or greater than a given level of protection.
</xs:documentation>
</xs:annotation>
@@ -524,7 +576,7 @@
so security is comparable to OpenID 2.0 relying parties.
</xs:documentation>
</xs:annotation>
- </xs:attribute>
+ </xs:attribute>
<xs:attribute name="unsolicitedAssertionVerification">
<xs:annotation>
<xs:documentation>
@@ -735,7 +787,7 @@
</xs:documentation>
</xs:annotation>
<xs:complexType>
-
+
</xs:complexType>
</xs:element>
</xs:choice>
@@ -856,7 +908,7 @@
<xs:attribute name="includeEventStatistics" type="xs:boolean" default="true">
<xs:annotation>
<xs:documentation>
- Whether a set of counters that track how often certain events (such as an
+ Whether a set of counters that track how often certain events (such as an
successful or failed authentication) is included in the report.
</xs:documentation>
</xs:annotation>
diff --git a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs
index 1bf2ebc..e138acd 100644
--- a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs
+++ b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs
@@ -81,6 +81,11 @@ namespace DotNetOpenAuth.Configuration {
private const string ProtectDownlevelReplayAttacksConfigName = "protectDownlevelReplayAttacks";
/// <summary>
+ /// The name of the &lt;trustedProviders&gt; sub-element.
+ /// </summary>
+ private const string TrustedProvidersElementName = "trustedProviders";
+
+ /// <summary>
/// Initializes a new instance of the <see cref="OpenIdRelyingPartySecuritySettingsElement"/> class.
/// </summary>
public OpenIdRelyingPartySecuritySettingsElement() {
@@ -235,6 +240,16 @@ namespace DotNetOpenAuth.Configuration {
}
/// <summary>
+ /// Gets or sets the set of trusted OpenID Provider Endpoints.
+ /// </summary>
+ [ConfigurationProperty(TrustedProvidersElementName, IsDefaultCollection = false)]
+ [ConfigurationCollection(typeof(TrustedProviderConfigurationCollection))]
+ public TrustedProviderConfigurationCollection TrustedProviders {
+ get { return (TrustedProviderConfigurationCollection)this[TrustedProvidersElementName] ?? new TrustedProviderConfigurationCollection(); }
+ set { this[TrustedProvidersElementName] = value; }
+ }
+
+ /// <summary>
/// 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>
@@ -256,6 +271,12 @@ namespace DotNetOpenAuth.Configuration {
settings.AllowApproximateIdentifierDiscovery = this.AllowApproximateIdentifierDiscovery;
settings.ProtectDownlevelReplayAttacks = this.ProtectDownlevelReplayAttacks;
+ settings.RejectAssertionsFromUntrustedProviders = this.TrustedProviders.RejectAssertionsFromUntrustedProviders;
+ foreach (TrustedProviderEndpointConfigurationElement opEndpoint in this.TrustedProviders) {
+ var endpointSetting = new RelyingPartySecuritySettings.TrustedProviderEndpointSettings(opEndpoint.AllowSubPath, opEndpoint.AllowAdditionalQueryParameters);
+ settings.TrustedProviderEndpoints.Add(opEndpoint.ProviderEndpoint, endpointSetting);
+ }
+
return settings;
}
}
diff --git a/src/DotNetOpenAuth/Configuration/TrustedProviderConfigurationCollection.cs b/src/DotNetOpenAuth/Configuration/TrustedProviderConfigurationCollection.cs
new file mode 100644
index 0000000..78c74e9
--- /dev/null
+++ b/src/DotNetOpenAuth/Configuration/TrustedProviderConfigurationCollection.cs
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------
+// <copyright file="TrustedProviderConfigurationCollection.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Configuration {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Diagnostics.Contracts;
+
+ /// <summary>
+ /// A configuration collection of trusted OP Endpoints.
+ /// </summary>
+ internal class TrustedProviderConfigurationCollection : ConfigurationElementCollection {
+ /// <summary>
+ /// The name of the "rejectAssertionsFromUntrustedProviders" element.
+ /// </summary>
+ private const string RejectAssertionsFromUntrustedProvidersConfigName = "rejectAssertionsFromUntrustedProviders";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TrustedProviderConfigurationCollection"/> class.
+ /// </summary>
+ internal TrustedProviderConfigurationCollection() {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TrustedProviderConfigurationCollection"/> class.
+ /// </summary>
+ internal TrustedProviderConfigurationCollection(IEnumerable<TrustedProviderEndpointConfigurationElement> elements) {
+ Contract.Requires<ArgumentNullException>(elements != null);
+
+ foreach (TrustedProviderEndpointConfigurationElement element in elements) {
+ this.BaseAdd(element);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether any login attempt coming from an OpenID Provider Endpoint that is not on this
+ /// whitelist of trusted OP Endpoints will be rejected. If the trusted providers list is empty and this value
+ /// is true, all assertions are rejected.
+ /// </summary>
+ [ConfigurationProperty(RejectAssertionsFromUntrustedProvidersConfigName, DefaultValue = false)]
+ internal bool RejectAssertionsFromUntrustedProviders {
+ get { return (bool)this[RejectAssertionsFromUntrustedProvidersConfigName]; }
+ set { this[RejectAssertionsFromUntrustedProvidersConfigName] = value; }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, creates a new <see cref="T:System.Configuration.ConfigurationElement"/>.
+ /// </summary>
+ /// <returns>
+ /// A new <see cref="T:System.Configuration.ConfigurationElement"/>.
+ /// </returns>
+ protected override ConfigurationElement CreateNewElement() {
+ return new TrustedProviderEndpointConfigurationElement();
+ }
+
+ /// <summary>
+ /// Gets the element key for a specified configuration element when overridden in a derived class.
+ /// </summary>
+ /// <param name="element">The <see cref="T:System.Configuration.ConfigurationElement"/> to return the key for.</param>
+ /// <returns>
+ /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>.
+ /// </returns>
+ protected override object GetElementKey(ConfigurationElement element) {
+ return ((TrustedProviderEndpointConfigurationElement)element).ProviderEndpoint;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/Configuration/TrustedProviderEndpointConfigurationElement.cs b/src/DotNetOpenAuth/Configuration/TrustedProviderEndpointConfigurationElement.cs
new file mode 100644
index 0000000..106b8b7
--- /dev/null
+++ b/src/DotNetOpenAuth/Configuration/TrustedProviderEndpointConfigurationElement.cs
@@ -0,0 +1,63 @@
+//-----------------------------------------------------------------------
+// <copyright file="TrustedProviderEndpoint.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Configuration {
+ using System;
+ using System.Configuration;
+
+ /// <summary>
+ /// A configuration element that records a trusted Provider Endpoint.
+ /// </summary>
+ internal class TrustedProviderEndpointConfigurationElement : ConfigurationElement {
+ /// <summary>
+ /// The name of the attribute that stores the <see cref="ProviderEndpoint"/> value.
+ /// </summary>
+ private const string ProviderEndpointConfigName = "endpoint";
+
+ /// <summary>
+ /// The name of the attribute that stores the <see cref="AllowSubPath"/> value.
+ /// </summary>
+ private const string AllowSubPathConfigName = "allowSubPath";
+
+ /// <summary>
+ /// The name of the attribute that stores the <see cref="AllowAdditionalQueryParameters"/> value.
+ /// </summary>
+ private const string AllowAdditionalQueryParametersConfigName = "allowAdditionalQueryParameters";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TrustedProviderEndpointConfigurationElement"/> class.
+ /// </summary>
+ public TrustedProviderEndpointConfigurationElement() {
+ }
+
+ /// <summary>
+ /// Gets or sets the OpenID Provider Endpoint (aka "OP Endpoint") that this relying party trusts.
+ /// </summary>
+ [ConfigurationProperty(ProviderEndpointConfigName, IsRequired = true, IsKey = true)]
+ public Uri ProviderEndpoint {
+ get { return (Uri)this[ProviderEndpointConfigName]; }
+ set { this[ProviderEndpointConfigName] = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the OP Endpoint given here is a base path, and sub-paths concatenated to it are equally trusted.
+ /// </summary>
+ [ConfigurationProperty(AllowSubPathConfigName, DefaultValue = false)]
+ public bool AllowSubPath {
+ get { return (bool)this[AllowSubPathConfigName]; }
+ set { this[AllowSubPathConfigName] = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the OP Endpoint given here is equally trusted if query string parameters are added to it.
+ /// </summary>
+ [ConfigurationProperty(AllowAdditionalQueryParametersConfigName, DefaultValue = false)]
+ public bool AllowAdditionalQueryParameters {
+ get { return (bool)this[AllowAdditionalQueryParametersConfigName]; }
+ set { this[AllowAdditionalQueryParametersConfigName] = value; }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index 4073bde..6517a87 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -295,6 +295,8 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="Configuration\OpenIdRelyingPartyElement.cs" />
<Compile Include="Configuration\OpenIdRelyingPartySecuritySettingsElement.cs" />
<Compile Include="Configuration\ReportingElement.cs" />
+ <Compile Include="Configuration\TrustedProviderConfigurationCollection.cs" />
+ <Compile Include="Configuration\TrustedProviderEndpointConfigurationElement.cs" />
<Compile Include="Configuration\TypeConfigurationCollection.cs" />
<Compile Include="Configuration\TypeConfigurationElement.cs" />
<Compile Include="Configuration\UntrustedWebRequestElement.cs" />
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs
index a7686c5..3031134 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs
@@ -8,6 +8,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
@@ -28,6 +30,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
this.PrivateSecretMaximumAge = TimeSpan.FromDays(7);
this.ProtectDownlevelReplayAttacks = ProtectDownlevelReplayAttacksDefault;
this.AllowApproximateIdentifierDiscovery = true;
+ this.TrustedProviderEndpoints = new Dictionary<Uri, TrustedProviderEndpointSettings>();
}
/// <summary>
@@ -143,6 +146,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
public bool AllowApproximateIdentifierDiscovery { get; set; }
/// <summary>
+ /// Gets the set of trusted OpenID Provider Endpoint URIs and settings that describe them.
+ /// </summary>
+ public IDictionary<Uri, TrustedProviderEndpointSettings> TrustedProviderEndpoints { get; private set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether any login attempt coming from an OpenID Provider Endpoint that is not on this
+ /// whitelist of trusted OP Endpoints will be rejected. If the trusted providers list is empty and this value
+ /// is true, all assertions are rejected.
+ /// </summary>
+ /// <value>Default is <c>false</c>.</value>
+ public bool RejectAssertionsFromUntrustedProviders { get; set; }
+
+ /// <summary>
/// Gets or sets a value indicating whether special measures are taken to
/// protect users from replay attacks when those users' identities are hosted
/// by OpenID 1.x Providers.
@@ -167,5 +183,30 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
.Where(se => !this.RejectDelegatingIdentifiers || se.ClaimedIdentifier == se.ProviderLocalIdentifier)
.Where(se => !this.RequireDirectedIdentity || se.ClaimedIdentifier == se.Protocol.ClaimedIdentifierForOPIdentifier);
}
+
+ /// <summary>
+ /// A trusted OpenID Provider endpoint and flags regarding how it is trusted.
+ /// </summary>
+ public class TrustedProviderEndpointSettings {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TrustedProviderEndpointSettings"/> class.
+ /// </summary>
+ /// <param name="allowSubPath">A value indicating whether the OP Endpoint given here is a base path, and sub-paths concatenated to it are equally trusted.</param>
+ /// <param name="allowAdditionalQueryParameters">A value indicating whether the OP Endpoint given here is equally trusted if query string parameters are added to it.</param>
+ public TrustedProviderEndpointSettings(bool allowSubPath = false, bool allowAdditionalQueryParameters = false) {
+ this.AllowSubPath = allowSubPath;
+ this.AllowAdditionalQueryParameters = allowAdditionalQueryParameters;
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the OP Endpoint given here is a base path, and sub-paths concatenated to it are equally trusted.
+ /// </summary>
+ public bool AllowSubPath { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the OP Endpoint given here is equally trusted if query string parameters are added to it.
+ /// </summary>
+ public bool AllowAdditionalQueryParameters { get; set; }
+ }
}
}