//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.Provider { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; using System.Linq; using DotNetOpenAuth.Messaging; /// /// Security settings that are applicable to providers. /// [Serializable] public sealed class ProviderSecuritySettings : SecuritySettings { /// /// The default value for the property. /// internal const bool ProtectDownlevelReplayAttacksDefault = true; /// /// The default value for the property. /// internal const bool EncodeAssociationSecretsInHandlesDefault = true; /// /// The default value for the property. /// internal const bool SignOutgoingExtensionsDefault = true; /// /// The default value for the property. /// internal const UnsolicitedAssertionVerificationLevel UnsolicitedAssertionVerificationDefault = UnsolicitedAssertionVerificationLevel.RequireSuccess; /// /// The subset of association types and their customized lifetimes. /// private IDictionary associationLifetimes = new Dictionary(); /// /// Initializes a new instance of the class. /// internal ProviderSecuritySettings() : base(true) { this.SignOutgoingExtensions = SignOutgoingExtensionsDefault; this.ProtectDownlevelReplayAttacks = ProtectDownlevelReplayAttacksDefault; this.UnsolicitedAssertionVerification = UnsolicitedAssertionVerificationDefault; } /// /// The behavior a Provider takes when verifying that it is authoritative for an /// identifier it is about to send an unsolicited assertion for. /// [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "By design")] public enum UnsolicitedAssertionVerificationLevel { /// /// Always verify that the Provider is authoritative for an identifier before /// sending an unsolicited assertion for it and fail if it is not. /// RequireSuccess, /// /// 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. /// LogWarningOnFailure, /// /// Never verify that the Provider is authoritative for an identifier before /// sending an unsolicited assertion for it. /// /// /// 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. /// NeverVerify, } /// /// Gets a subset of the available association types and their /// customized maximum lifetimes. /// public IDictionary AssociationLifetimes { get { return this.associationLifetimes; } } /// /// Gets or sets a value indicating whether Relying Party discovery will only /// succeed if done over a secure HTTPS channel. /// /// Default is false. public bool RequireSsl { get; set; } /// /// Gets or sets the level of verification a Provider performs on an identifier before /// sending an unsolicited assertion for it. /// /// The default value is . public UnsolicitedAssertionVerificationLevel UnsolicitedAssertionVerification { get; set; } /// /// Gets or sets a value indicating whether the Provider should ease the burden of storing associations /// by encoding them in signed, encrypted form into the association handles themselves, storing only /// a few rotating, private symmetric keys in the Provider's store instead. /// /// The default value for this property is true. public bool EncodeAssociationSecretsInHandles { get; set; } /// /// 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. /// /// The default value is true. /// /// Nonces for protection against replay attacks were not mandated /// by OpenID 1.x, which leaves users open to replay attacks. /// This feature works by preventing associations from being used /// with OpenID 1.x relying parties, thereby forcing them into /// "dumb" mode and verifying every claim with this provider. /// This gives the provider an opportunity to verify its own nonce /// to protect against replay attacks. /// internal bool ProtectDownlevelReplayAttacks { get; set; } /// /// Gets or sets a value indicating whether outgoing extensions are always signed. /// /// /// true if outgoing extensions should be signed; otherwise, false. /// The default is true. /// /// /// This property is internal because Providers should never turn it off, but it is /// needed for testing the RP's rejection of unsigned extensions. /// internal bool SignOutgoingExtensions { get; set; } /// /// Creates a deep clone of this instance. /// /// A new instance that is a deep clone of this instance. internal ProviderSecuritySettings Clone() { var securitySettings = new ProviderSecuritySettings(); foreach (var pair in this.AssociationLifetimes) { securitySettings.AssociationLifetimes.Add(pair); } securitySettings.MaximumHashBitLength = this.MaximumHashBitLength; securitySettings.MinimumHashBitLength = this.MinimumHashBitLength; securitySettings.ProtectDownlevelReplayAttacks = this.ProtectDownlevelReplayAttacks; securitySettings.RequireSsl = this.RequireSsl; securitySettings.SignOutgoingExtensions = this.SignOutgoingExtensions; securitySettings.UnsolicitedAssertionVerification = this.UnsolicitedAssertionVerification; return securitySettings; } } }