diff options
Diffstat (limited to 'src/DotNetOpenAuth.OpenId')
13 files changed, 135 insertions, 34 deletions
diff --git a/src/DotNetOpenAuth.OpenId/Configuration/HostMetaDiscoveryElement.cs b/src/DotNetOpenAuth.OpenId/Configuration/HostMetaDiscoveryElement.cs new file mode 100644 index 0000000..437b12f --- /dev/null +++ b/src/DotNetOpenAuth.OpenId/Configuration/HostMetaDiscoveryElement.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------- +// <copyright file="HostMetaDiscoveryElement.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Configuration { + using System.Configuration; + + /// <summary> + /// The configuration element that can adjust how hostmeta discovery works. + /// </summary> + internal class HostMetaDiscoveryElement : ConfigurationElement { + /// <summary> + /// The property name for enableCertificateValidationCache. + /// </summary> + private const string EnableCertificateValidationCacheConfigName = "enableCertificateValidationCache"; + + /// <summary> + /// Initializes a new instance of the <see cref="HostMetaDiscoveryElement"/> class. + /// </summary> + public HostMetaDiscoveryElement() { + } + + /// <summary> + /// Gets or sets a value indicating whether validated certificates should be cached and not validated again. + /// </summary> + /// <remarks> + /// This helps to avoid unexplained 5-10 second delays in certificate validation for Google Apps for Domains that impact some servers. + /// </remarks> + [ConfigurationProperty(EnableCertificateValidationCacheConfigName, DefaultValue = false)] + public bool EnableCertificateValidationCache { + get { return (bool)this[EnableCertificateValidationCacheConfigName]; } + set { this[EnableCertificateValidationCacheConfigName] = value; } + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartyElement.cs b/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartyElement.cs index 749659e..8af1129 100644 --- a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartyElement.cs +++ b/src/DotNetOpenAuth.OpenId/Configuration/OpenIdRelyingPartyElement.cs @@ -47,9 +47,15 @@ namespace DotNetOpenAuth.Configuration { private const string DiscoveryServicesElementName = "discoveryServices"; /// <summary> + /// The name of the <hostMetaDiscovery> sub-element. + /// </summary> + private const string HostMetaDiscoveryElementName = "hostMetaDiscovery"; + + /// <summary> /// The built-in set of identifier discovery services. /// </summary> - private static readonly TypeConfigurationCollection<IIdentifierDiscoveryService> defaultDiscoveryServices = new TypeConfigurationCollection<IIdentifierDiscoveryService>(new Type[] { typeof(UriDiscoveryService), typeof(XriDiscoveryProxyService) }); + private static readonly TypeConfigurationCollection<IIdentifierDiscoveryService> defaultDiscoveryServices = + new TypeConfigurationCollection<IIdentifierDiscoveryService>(new Type[] { typeof(UriDiscoveryService), typeof(XriDiscoveryProxyService) }); /// <summary> /// Initializes a new instance of the <see cref="OpenIdRelyingPartyElement"/> class. @@ -98,6 +104,15 @@ namespace DotNetOpenAuth.Configuration { } /// <summary> + /// Gets or sets the host meta discovery configuration element. + /// </summary> + [ConfigurationProperty(HostMetaDiscoveryElementName)] + internal HostMetaDiscoveryElement HostMetaDiscovery { + get { return (HostMetaDiscoveryElement)this[HostMetaDiscoveryElementName] ?? new HostMetaDiscoveryElement(); } + set { this[HostMetaDiscoveryElementName] = value; } + } + + /// <summary> /// Gets or sets the services to use for discovering service endpoints for identifiers. /// </summary> /// <remarks> diff --git a/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj b/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj index 95dccc1..75bd113 100644 --- a/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj +++ b/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj @@ -22,6 +22,7 @@ <ItemGroup> <Compile Include="Configuration\AssociationTypeCollection.cs" /> <Compile Include="Configuration\AssociationTypeElement.cs" /> + <Compile Include="Configuration\HostMetaDiscoveryElement.cs" /> <Compile Include="Configuration\OpenIdElement.cs" /> <Compile Include="Configuration\OpenIdProviderElement.cs" /> <Compile Include="Configuration\OpenIdProviderSecuritySettingsElement.cs" /> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Association.cs b/src/DotNetOpenAuth.OpenId/OpenId/Association.cs index 764f4fa..a0f5bae 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Association.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Association.cs @@ -240,7 +240,7 @@ namespace DotNetOpenAuth.OpenId { /// A hash code for the current <see cref="T:System.Object"/>. /// </returns> public override int GetHashCode() { - HMACSHA1 hmac = new HMACSHA1(this.SecretKey); + var hmac = HmacAlgorithms.Create(HmacAlgorithms.HmacSha1, this.SecretKey); try { CryptoStream cs = new CryptoStream(Stream.Null, hmac, CryptoStreamMode.Write); diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs index ec16fae..912a322 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs @@ -195,9 +195,14 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { try { if (cryptoKey == null) { cryptoKey = this.cryptoKeyStore.GetKey(SecretUri.AbsoluteUri, returnToParameters[ReturnToSignatureHandleParameterName]); + ErrorUtilities.VerifyProtocol( + cryptoKey != null, + MessagingStrings.MissingDecryptionKeyForHandle, + SecretUri.AbsoluteUri, + returnToParameters[ReturnToSignatureHandleParameterName]); } - using (var signer = new HMACSHA256(cryptoKey.Key)) { + using (var signer = HmacAlgorithms.Create(HmacAlgorithms.HmacSha256, cryptoKey.Key)) { signature = signer.ComputeHash(bytesToSign); } } catch (ProtocolException ex) { diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionArgumentsManager.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionArgumentsManager.cs index 5cd4904..1d795da 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionArgumentsManager.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionArgumentsManager.cs @@ -21,7 +21,7 @@ namespace DotNetOpenAuth.OpenId.Extensions { /// match to namespaces for backward compatibility with other OpenID libraries. /// </summary> private static readonly Dictionary<string, string> typeUriToAliasAffinity = new Dictionary<string, string> { - { Extensions.SimpleRegistration.Constants.sreg_ns, Extensions.SimpleRegistration.Constants.sreg_compatibility_alias }, + { Extensions.SimpleRegistration.Constants.TypeUris.Standard, Extensions.SimpleRegistration.Constants.sreg_compatibility_alias }, { Extensions.ProviderAuthenticationPolicy.Constants.TypeUri, Extensions.ProviderAuthenticationPolicy.Constants.CompatibilityAlias }, }; diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs index 373134d..880a25e 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs @@ -71,10 +71,10 @@ namespace DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy { /// actively authenticated to the OP in a manner fitting the asserted policies. /// </summary> /// <remarks> - /// If the RP's request included the "openid.max_auth_age" parameter - /// then the OP MUST include "openid.auth_time" in its response. - /// If "openid.max_auth_age" was not requested, the OP MAY choose to include - /// "openid.auth_time" in its response. + /// If the RP's request included the "openid.pape.max_auth_age" parameter + /// then the OP MUST include "openid.pape.auth_time" in its response. + /// If "openid.pape.max_auth_age" was not requested, the OP MAY choose to include + /// "openid.pape.auth_time" in its response. /// </remarks> [MessagePart("auth_time", Encoder = typeof(DateTimeEncoder))] public DateTime? AuthenticationTimeUtc { diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs index 9d418ee..ab08cbb 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs @@ -24,7 +24,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { /// The factory method that may be used in deserialization of this message. /// </summary> internal static readonly StandardOpenIdExtensionFactory.CreateDelegate Factory = (typeUri, data, baseMessage, isProviderRole) => { - if (typeUri == Constants.sreg_ns && isProviderRole) { + if (typeUri == Constants.TypeUris.Standard && isProviderRole) { return new ClaimsRequest(typeUri); } @@ -41,7 +41,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { /// Initializes a new instance of the <see cref="ClaimsRequest"/> class. /// </summary> public ClaimsRequest() - : base(new Version(1, 0), Constants.sreg_ns, Constants.AdditionalTypeUris) { + : base(new Version(1, 0), Constants.TypeUris.Standard, Constants.AdditionalTypeUris) { } /// <summary> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs index 999fe8d..a313519 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs @@ -27,7 +27,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { /// The factory method that may be used in deserialization of this message. /// </summary> internal static readonly StandardOpenIdExtensionFactory.CreateDelegate Factory = (typeUri, data, baseMessage, isProviderRole) => { - if ((typeUri == Constants.sreg_ns || Array.IndexOf(Constants.AdditionalTypeUris, typeUri) >= 0) && !isProviderRole) { + if ((typeUri == Constants.TypeUris.Standard || Array.IndexOf(Constants.AdditionalTypeUris, typeUri) >= 0) && !isProviderRole) { return new ClaimsResponse(typeUri); } @@ -55,10 +55,11 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { private CultureInfo culture; /// <summary> - /// Initializes a new instance of the <see cref="ClaimsResponse"/> class. + /// Initializes a new instance of the <see cref="ClaimsResponse"/> class + /// using the most common, and spec prescribed type URI. /// </summary> - internal ClaimsResponse() - : this(Constants.sreg_ns) { + public ClaimsResponse() + : this(Constants.TypeUris.Standard) { } /// <summary> @@ -67,8 +68,10 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { /// <param name="typeUriToUse"> /// The type URI that must be used to identify this extension in the response message. /// This value should be the same one the relying party used to send the extension request. + /// Commonly used type URIs supported by relying parties are defined in the + /// <see cref="Constants.TypeUris"/> class. /// </param> - internal ClaimsResponse(string typeUriToUse) + public ClaimsResponse(string typeUriToUse = Constants.TypeUris.Standard) : base(new Version(1, 0), typeUriToUse, Constants.AdditionalTypeUris) { Requires.NotNullOrEmpty(typeUriToUse, "typeUriToUse"); } @@ -189,7 +192,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { } /// <summary> - /// Gets or sets a combination o the language and country of the user. + /// Gets or sets a combination of the language and country of the user. /// </summary> [XmlIgnore] public CultureInfo Culture { @@ -200,7 +203,16 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { if (!string.IsNullOrEmpty(this.Country)) { cultureString += "-" + this.Country; } - this.culture = CultureInfo.GetCultureInfo(cultureString); + + // language-country may not always form a recongized valid culture. + // For instance, a Google OpenID Provider can return a random combination + // of language and country based on user settings. + try { + this.culture = CultureInfo.GetCultureInfo(cultureString); + } catch (ArgumentException) { // CultureNotFoundException derives from this, and .NET 3.5 throws the base type + // Fallback to just reporting a culture based on language. + this.culture = CultureInfo.GetCultureInfo(this.Language); + } } return this.culture; diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/Constants.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/Constants.cs index 8325b0c..30cd748 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/Constants.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/SimpleRegistration/Constants.cs @@ -13,10 +13,31 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { /// <summary> /// Simple Registration constants /// </summary> - internal static class Constants { - internal const string sreg_ns = "http://openid.net/extensions/sreg/1.1"; - internal const string sreg_ns10 = "http://openid.net/sreg/1.0"; - internal const string sreg_ns11other = "http://openid.net/sreg/1.1"; + public static class Constants { + /// <summary> + /// Commonly used type URIs to represent the Simple Registration extension. + /// </summary> + public static class TypeUris { + /// <summary> + /// The URI "http://openid.net/extensions/sreg/1.1". + /// </summary> + /// <remarks> + /// This is the type URI prescribed by the Simple Registration 1.1 spec. + /// http://openid.net/specs/openid-simple-registration-extension-1_1-01.html#anchor3 + /// </remarks> + public const string Standard = "http://openid.net/extensions/sreg/1.1"; + + /// <summary> + /// The URI "http://openid.net/sreg/1.0" + /// </summary> + public const string Variant10 = "http://openid.net/sreg/1.0"; + + /// <summary> + /// The URI "http://openid.net/sreg/1.1" + /// </summary> + public const string Variant11 = "http://openid.net/sreg/1.1"; + } + internal const string sreg_compatibility_alias = "sreg"; internal const string policy_url = "policy_url"; internal const string optional = "optional"; @@ -39,8 +60,8 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration { /// Additional type URIs that this extension is sometimes known by remote parties. /// </summary> internal static readonly string[] AdditionalTypeUris = new string[] { - Constants.sreg_ns10, - Constants.sreg_ns11other, + Constants.TypeUris.Variant10, + Constants.TypeUris.Variant11, }; } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs b/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs index 5e3553d..bf0111d 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/HmacShaAssociation.cs @@ -226,22 +226,22 @@ namespace DotNetOpenAuth.OpenId { private static HmacSha[] CreateAssociationTypes() { return new[] { new HmacSha { - CreateHasher = secretKey => new HMACSHA512(secretKey), + HmacAlgorithmName = HmacAlgorithms.HmacSha384, GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA512, BaseHashAlgorithm = SHA512.Create(), }, new HmacSha { - CreateHasher = secretKey => new HMACSHA384(secretKey), + HmacAlgorithmName = HmacAlgorithms.HmacSha384, GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA384, BaseHashAlgorithm = SHA384.Create(), }, new HmacSha { - CreateHasher = secretKey => new HMACSHA256(secretKey), + HmacAlgorithmName = HmacAlgorithms.HmacSha256, GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA256, BaseHashAlgorithm = SHA256.Create(), }, new HmacSha { - CreateHasher = secretKey => new HMACSHA1(secretKey), + HmacAlgorithmName = HmacAlgorithms.HmacSha1, GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA1, BaseHashAlgorithm = SHA1.Create(), }, @@ -258,9 +258,9 @@ namespace DotNetOpenAuth.OpenId { internal Func<Protocol, string> GetAssociationType { get; set; } /// <summary> - /// Gets or sets a function that will create the <see cref="HashAlgorithm"/> using a given shared secret for the mac. + /// Gets or sets the name of the HMAC-SHA algorithm. (e.g. "HMAC-SHA256") /// </summary> - internal Func<byte[], HashAlgorithm> CreateHasher { get; set; } + internal string HmacAlgorithmName { get; set; } /// <summary> /// Gets or sets the base hash algorithm. @@ -271,6 +271,15 @@ namespace DotNetOpenAuth.OpenId { /// Gets the size of the hash (in bytes). /// </summary> internal int SecretLength { get { return this.BaseHashAlgorithm.HashSize / 8; } } + + /// <summary> + /// Creates the <see cref="HashAlgorithm"/> using a given shared secret for the mac. + /// </summary> + /// <param name="secret">The HMAC secret.</param> + /// <returns>The algorithm.</returns> + internal HashAlgorithm CreateHasher(byte[] secret) { + return HmacAlgorithms.Create(this.HmacAlgorithmName, secret); + } } } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs b/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs index 28e4df0..8f1baed 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs @@ -116,11 +116,7 @@ namespace DotNetOpenAuth.OpenId { Requires.ValidState(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired); Contract.Ensures(Contract.Result<Realm>() != null); - HttpRequestBase requestInfo = new HttpRequestWrapper(HttpContext.Current.Request); - UriBuilder realmUrl = new UriBuilder(requestInfo.GetPublicFacingUrl()); - realmUrl.Path = HttpContext.Current.Request.ApplicationPath; - realmUrl.Query = null; - realmUrl.Fragment = null; + var realmUrl = new UriBuilder(MessagingUtilities.GetWebRoot()); // For RP discovery, the realm url MUST NOT redirect. To prevent this for // virtual directory hosted apps, we need to make sure that the realm path ends diff --git a/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs index 631eab6..41417de 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/UriIdentifier.cs @@ -69,6 +69,11 @@ namespace DotNetOpenAuth.OpenId { /// </remarks> [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Some things just can't be done in a field initializer.")] static UriIdentifier() { + if (Type.GetType("Mono.Runtime") != null) { + // Uri scheme registration doesn't work on mono. + return; + } + // Our first attempt to handle trailing periods in path segments is to leverage // full trust if it's available to rewrite the rules. // In fact this is the ONLY way in .NET 3.5 (and arguably in .NET 4.0) to send |