diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-06-01 20:51:04 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-06-02 16:59:50 -0700 |
commit | 11be1a031e76839c02b663c2efebdbbbfad8d775 (patch) | |
tree | fcfc742783668eeba3b437a3dd59f42a64a0f095 /src | |
parent | f594aa3a0d0399f57858dc9933b3437dd60b63a1 (diff) | |
download | DotNetOpenAuth-11be1a031e76839c02b663c2efebdbbbfad8d775.zip DotNetOpenAuth-11be1a031e76839c02b663c2efebdbbbfad8d775.tar.gz DotNetOpenAuth-11be1a031e76839c02b663c2efebdbbbfad8d775.tar.bz2 |
Working RP and OP samples demonstrating the GSA profile.
But I need to refactor the ISecurityProfile so that OPs can support the GSA profile without requiring that all RPs comply with it's RequireSsl setting for RP discovery.
Diffstat (limited to 'src')
6 files changed, 60 insertions, 14 deletions
diff --git a/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs index 7a547dd..a2db09f 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs @@ -200,6 +200,18 @@ namespace DotNetOpenAuth.OpenId.Provider { this.positiveResponse.ClaimedIdentifier = builder.Uri; } + /// <summary> + /// Sets the Claimed and Local identifiers even after they have been initially set. + /// </summary> + /// <param name="identifier">The value to set to the <see cref="ClaimedIdentifier"/> and <see cref="LocalIdentifier"/> properties.</param> + internal void ResetClaimedAndLocalIdentifiers(Identifier identifier) { + Contract.RequiresAlways(identifier != null); + ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier"); + + this.positiveResponse.ClaimedIdentifier = identifier; + this.positiveResponse.LocalIdentifier = identifier; + } + #endregion } } diff --git a/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs index 2744fcf..5de245c 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs @@ -105,7 +105,7 @@ namespace DotNetOpenAuth.OpenId.Provider { /// See OpenID Authentication 2.0 spec section 9.2.1. /// </remarks> public RelyingPartyDiscoveryResult IsReturnUrlDiscoverable(OpenIdProvider provider) { - Contract.Requires<ArgumentNullException>(provider != null); + Contract.RequiresAlways(provider != null); ErrorUtilities.VerifyArgumentNotNull(provider, "provider"); if (!this.realmDiscoveryResult.HasValue) { diff --git a/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs b/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs index 8372b8f..43b258c 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs @@ -123,6 +123,11 @@ namespace DotNetOpenAuth.OpenId.Provider { ErrorUtilities.VerifyArgumentNotNull(localIdentifier, "localIdentifier"); ErrorUtilities.VerifyArgumentNotNull(relyingPartyRealm, "relyingPartyRealm"); + if (localIdentifier.ToString().StartsWith(this.BaseIdentifier.AbsoluteUri, StringComparison.Ordinal)) { + Logger.OpenId.Warn("Trying to generate a PPID from a PPID. Returning original PPID."); + return new Uri(localIdentifier); + } + byte[] salt = this.GetHashSaltForLocalIdentifier(localIdentifier); string valueToHash = localIdentifier + "#"; switch (this.PairwiseUnique) { diff --git a/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.Designer.cs b/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.Designer.cs index 94b3ffb..8ff10c0 100644 --- a/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.Designer.cs +++ b/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.Designer.cs @@ -97,6 +97,15 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { } /// <summary> + /// Looks up a localized string similar to No PPID provider has been configured.. + /// </summary> + internal static string PpidProviderNotGiven { + get { + return ResourceManager.GetString("PpidProviderNotGiven", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to Discovery on the Realm URL MUST be performed before sending a positive assertion.. /// </summary> internal static string RealmDiscoveryNotPerformed { diff --git a/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.resx b/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.resx index 1c8fc7e..04d53d4 100644 --- a/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.resx +++ b/src/DotNetOpenAuth/OpenId/SecurityProfiles/SecurityProfileStrings.resx @@ -129,6 +129,9 @@ <data name="PiiRequestedWithNoPiiPolicy" xml:space="preserve"> <value>No personally identifiable information should be requested when the http://www.idmanagement.gov/schema/2009/05/icam/no-pii.pdf PAPE policy is present.</value> </data> + <data name="PpidProviderNotGiven" xml:space="preserve"> + <value>No PPID provider has been configured.</value> + </data> <data name="RealmDiscoveryNotPerformed" xml:space="preserve"> <value>Discovery on the Realm URL MUST be performed before sending a positive assertion.</value> </data> diff --git a/src/DotNetOpenAuth/OpenId/SecurityProfiles/USGovernmentLevel1.cs b/src/DotNetOpenAuth/OpenId/SecurityProfiles/USGovernmentLevel1.cs index 04fa772..b0e92f9 100644 --- a/src/DotNetOpenAuth/OpenId/SecurityProfiles/USGovernmentLevel1.cs +++ b/src/DotNetOpenAuth/OpenId/SecurityProfiles/USGovernmentLevel1.cs @@ -33,10 +33,25 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { private static readonly TimeSpan MaximumAssociationLifetime = TimeSpan.FromSeconds(86400); /// <summary> + /// Initializes a new instance of the <see cref="USGovernmentLevel1"/> class. + /// </summary> + public USGovernmentLevel1() { + AllowPersonallyIdentifiableInformation = true; + DisableSslRequirement = true; + } + + /// <summary> + /// Gets or sets the provider for generating PPID identifiers. + /// </summary> + public static IDirectedIdentityIdentifierProvider PpidIdentifierProvider { get; set; } + + /// <summary> /// Gets or sets a value indicating whether PII is allowed to be requested or received via OpenID. /// </summary> /// <value>The default value is <c>false</c>.</value> - public bool AllowPersonallyIdentifiableInformation { get; set; } + public static bool AllowPersonallyIdentifiableInformation { get; set; } + + public static bool DisableSslRequirement { get; set; } #region ISecurityProfile Members @@ -58,7 +73,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { var rpSecuritySettings = securitySettings as RelyingPartySecuritySettings; if (rpSecuritySettings != null) { - rpSecuritySettings.RequireSsl = true; + rpSecuritySettings.RequireSsl = !DisableSslRequirement; rpSecuritySettings.RequireDirectedIdentity = true; rpSecuritySettings.RequireAssociation = true; rpSecuritySettings.RejectDelegatingIdentifiers = true; @@ -68,7 +83,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { var opSecuritySettings = securitySettings as ProviderSecuritySettings; if (opSecuritySettings != null) { - opSecuritySettings.RequireSsl = true; + opSecuritySettings.RequireSsl = !DisableSslRequirement; SetMaximumAssociationLifetimeToNotExceed(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA256, MaximumAssociationLifetime, opSecuritySettings); SetMaximumAssociationLifetimeToNotExceed(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1, MaximumAssociationLifetime, opSecuritySettings); } @@ -89,7 +104,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { var rpSecuritySettings = securitySettings as RelyingPartySecuritySettings; if (rpSecuritySettings != null) { - ErrorUtilities.VerifyProtocol(rpSecuritySettings.RequireSsl, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); + ErrorUtilities.VerifyProtocol(rpSecuritySettings.RequireSsl || DisableSslRequirement, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); ErrorUtilities.VerifyProtocol(rpSecuritySettings.RequireDirectedIdentity, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); ErrorUtilities.VerifyProtocol(rpSecuritySettings.RequireAssociation, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); ErrorUtilities.VerifyProtocol(rpSecuritySettings.IgnoreUnsignedExtensions, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); @@ -97,7 +112,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { var opSecuritySettings = securitySettings as ProviderSecuritySettings; if (opSecuritySettings != null) { - ErrorUtilities.VerifyProtocol(opSecuritySettings.RequireSsl, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); + ErrorUtilities.VerifyProtocol(opSecuritySettings.RequireSsl || DisableSslRequirement, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); ErrorUtilities.VerifyProtocol(opSecuritySettings.AssociationLifetimes.ContainsKey(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA256) && opSecuritySettings.AssociationLifetimes[Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA256] <= MaximumAssociationLifetime, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); ErrorUtilities.VerifyProtocol(opSecuritySettings.AssociationLifetimes.ContainsKey(Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1) && opSecuritySettings.AssociationLifetimes[Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1] <= MaximumAssociationLifetime, SecurityProfileStrings.SecuritySettingsNotCompliantWithProfile, this.GetType().Name); } @@ -117,7 +132,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { ErrorUtilities.VerifyArgumentNotNull(request, "request"); RelyingParty.AuthenticationRequest requestInternal = (RelyingParty.AuthenticationRequest)request; - ErrorUtilities.VerifyProtocol(string.Equals(request.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal), SecurityProfileStrings.RealmMustBeHttps); + ErrorUtilities.VerifyProtocol(string.Equals(request.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal) || DisableSslRequirement, SecurityProfileStrings.RealmMustBeHttps); var pape = requestInternal.AppliedExtensions.OfType<PolicyRequest>().SingleOrDefault(); if (pape == null) { @@ -132,7 +147,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { pape.PreferredPolicies.Add(AuthenticationPolicies.USGovernmentTrustLevel1); } - if (!this.AllowPersonallyIdentifiableInformation && !pape.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { + if (!AllowPersonallyIdentifiableInformation && !pape.PreferredPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { pape.PreferredPolicies.Add(AuthenticationPolicies.NoPersonallyIdentifiableInformation); } @@ -160,7 +175,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { pape.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier), SecurityProfileStrings.PapeResponseOrRequiredPoliciesMissing); - ErrorUtilities.VerifyProtocol(this.AllowPersonallyIdentifiableInformation || pape.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation), SecurityProfileStrings.PapeResponseOrRequiredPoliciesMissing); + ErrorUtilities.VerifyProtocol(AllowPersonallyIdentifiableInformation || pape.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation), SecurityProfileStrings.PapeResponseOrRequiredPoliciesMissing); if (pape.ActualPolicies.Contains(AuthenticationPolicies.NoPersonallyIdentifiableInformation)) { ErrorUtilities.VerifyProtocol( @@ -191,7 +206,7 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.USGovernmentTrustLevel1)) { // Whenever we see this GSA policy requested, we MUST also see the PPID policy requested. ErrorUtilities.VerifyProtocol(papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier), SecurityProfileStrings.PapeRequestMissingRequiredPolicies); - ErrorUtilities.VerifyProtocol(string.Equals(hostProcessedRequest.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal), SecurityProfileStrings.RealmMustBeHttps); + ErrorUtilities.VerifyProtocol(string.Equals(hostProcessedRequest.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal) || DisableSslRequirement, SecurityProfileStrings.RealmMustBeHttps); } } } @@ -237,8 +252,10 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { if (papeRequest.PreferredPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { ErrorUtilities.VerifyProtocol(request.ClaimedIdentifier == request.LocalIdentifier, OpenIdStrings.DelegatingIdentifiersNotAllowed); - // Generate a PPID from the ClaimedIdentifier. - throw new NotImplementedException(); + // Mask the user's identity with a PPID. + ErrorUtilities.VerifyHost(PpidIdentifierProvider != null, SecurityProfileStrings.PpidProviderNotGiven); + Identifier ppidIdentifier = PpidIdentifierProvider.GetIdentifier(request.LocalIdentifier, request.Realm); + requestInternal.ResetClaimedAndLocalIdentifiers(ppidIdentifier); // Indicate that the RP is receiving a PPID claimed_id if (!papeResponse.ActualPolicies.Contains(AuthenticationPolicies.PrivatePersonalIdentifier)) { @@ -271,8 +288,8 @@ namespace DotNetOpenAuth.OpenId.SecurityProfiles { /// <param name="maximumLifetime">The maximum lifetime.</param> /// <param name="securitySettings">The security settings to adjust.</param> private static void SetMaximumAssociationLifetimeToNotExceed(string associationType, TimeSpan maximumLifetime, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType)); - Contract.Requires<ArgumentOutOfRangeException>(maximumLifetime.TotalSeconds > 0); + Contract.RequiresAlways(!String.IsNullOrEmpty(associationType)); + Contract.RequiresAlways(maximumLifetime.TotalSeconds > 0); if (!securitySettings.AssociationLifetimes.ContainsKey(associationType) || securitySettings.AssociationLifetimes[associationType] > maximumLifetime) { securitySettings.AssociationLifetimes[associationType] = maximumLifetime; |