public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, SecuritySettings securityRequirements) { var keyWithoutHandle = "assoc-" + distinguishingFactor.ToString(); var wrapper = Current.GetFromCache<Wrapper>(keyWithoutHandle); if(wrapper == null) return null; return Association.Deserialize(wrapper.Handle, wrapper.Expires, wrapper.PrivateData); }
/// <summary> /// Gets the best association (the one with the longest remaining life) for a given key. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="securityRequirements">The security requirements that the returned association must meet.</param> /// <returns> /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key. /// </returns> /// <remarks> /// In the event that multiple associations exist for the given /// <paramref name="distinguishingFactor"/>, it is important for the /// implementation for this method to use the <paramref name="securityRequirements"/> /// to pick the best (highest grade or longest living as the host's policy may dictate) /// association that fits the security requirements. /// Associations that are returned that do not meet the security requirements will be /// ignored and a new association created. /// </remarks> public Association GetAssociation(Uri distinguishingFactor, SecuritySettings securityRequirements) { using (var dataContext = new TransactedDatabaseEntities(System.Data.IsolationLevel.ReadCommitted)) { var relevantAssociations = from assoc in dataContext.OpenIdAssociations where assoc.DistinguishingFactor == distinguishingFactor.AbsoluteUri where assoc.ExpirationUtc > DateTime.UtcNow where assoc.PrivateDataLength * 8 >= securityRequirements.MinimumHashBitLength where assoc.PrivateDataLength * 8 <= securityRequirements.MaximumHashBitLength orderby assoc.ExpirationUtc descending select assoc; var qualifyingAssociations = relevantAssociations.AsEnumerable() .Select(assoc => DeserializeAssociation(assoc)); return qualifyingAssociations.FirstOrDefault(); } }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, SecuritySettings securitySettings) { // TODO: properly consider the securitySettings when picking an association to return. // properly escape the URL to prevent injection attacks. string value = distinguishingFactor.ToString(); string filter = string.Format( CultureInfo.InvariantCulture, "{0} = '{1}'", dataSet.Association.DistinguishingFactorColumn.ColumnName, value); string sort = dataSet.Association.ExpiresColumn.ColumnName + " DESC"; DataView view = new DataView(dataSet.Association, filter, sort, DataViewRowState.CurrentRows); if (view.Count == 0) { return null; } var row = (CustomStoreDataSet.AssociationRow)view[0].Row; return Association.Deserialize(row.Handle, row.Expires.ToUniversalTime(), row.PrivateData); }
/// <summary> /// Looks for the first association type in a preferred-order list that is /// likely to be supported given a specific OpenID version and the security settings, /// and perhaps a matching Diffie-Hellman session type. /// </summary> /// <param name="protocol">The OpenID version that dictates which associations are available.</param> /// <param name="highSecurityIsBetter">A value indicating whether to consider higher strength security to be better. Use <c>true</c> for initial association requests from the Relying Party; use <c>false</c> from Providers when the Relying Party asks for an unrecognized association in order to pick a suggested alternative that is likely to be supported on both sides.</param> /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param> /// <param name="requireMatchingDHSessionType">Use <c>true</c> for HTTP associations, <c>false</c> for HTTPS associations.</param> /// <param name="associationType">The resulting association type's well known protocol name. (i.e. HMAC-SHA256)</param> /// <param name="sessionType">The resulting session type's well known protocol name, if a matching one is available. (i.e. DH-SHA256)</param> /// <returns> /// True if a qualifying association could be found; false otherwise. /// </returns> internal static bool TryFindBestAssociation(Protocol protocol, bool highSecurityIsBetter, SecuritySettings securityRequirements, bool requireMatchingDHSessionType, out string associationType, out string sessionType) { Contract.Requires<ArgumentNullException>(protocol != null); Contract.Requires<ArgumentNullException>(securityRequirements != null); associationType = null; sessionType = null; // We use AsEnumerable() to avoid VerificationException (http://stackoverflow.com/questions/478422/why-does-simple-array-and-linq-generate-verificationexception-operation-could-de) IEnumerable<HmacSha> preferredOrder = highSecurityIsBetter ? hmacShaAssociationTypes.AsEnumerable() : hmacShaAssociationTypes.Reverse(); foreach (HmacSha sha in preferredOrder) { int hashSizeInBits = sha.SecretLength * 8; if (hashSizeInBits > securityRequirements.MaximumHashBitLength || hashSizeInBits < securityRequirements.MinimumHashBitLength) { continue; } sessionType = DiffieHellmanUtilities.GetNameForSize(protocol, hashSizeInBits); if (requireMatchingDHSessionType && sessionType == null) { continue; } associationType = sha.GetAssociationType(protocol); if (associationType == null) { continue; } return true; } return false; }
/// <summary> /// Gets the best association (the one with the longest remaining life) for a given key. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="securitySettings">The security settings.</param> /// <returns> /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key. /// </returns> public Association GetAssociation(TKey distinguishingFactor, SecuritySettings securitySettings) { lock (this) { return(this.GetServerAssociations(distinguishingFactor).Best.FirstOrDefault(assoc => securitySettings.IsAssociationInPermittedRange(assoc))); } }