summaryrefslogtreecommitdiffstats
path: root/projecttemplates/RelyingPartyLogic/RelyingPartyApplicationDbStore.cs
diff options
context:
space:
mode:
Diffstat (limited to 'projecttemplates/RelyingPartyLogic/RelyingPartyApplicationDbStore.cs')
-rw-r--r--projecttemplates/RelyingPartyLogic/RelyingPartyApplicationDbStore.cs130
1 files changed, 33 insertions, 97 deletions
diff --git a/projecttemplates/RelyingPartyLogic/RelyingPartyApplicationDbStore.cs b/projecttemplates/RelyingPartyLogic/RelyingPartyApplicationDbStore.cs
index e13633a..90a5544 100644
--- a/projecttemplates/RelyingPartyLogic/RelyingPartyApplicationDbStore.cs
+++ b/projecttemplates/RelyingPartyLogic/RelyingPartyApplicationDbStore.cs
@@ -9,120 +9,73 @@ namespace RelyingPartyLogic {
using System.Collections.Generic;
using System.Data;
using System.Linq;
- using System.Text;
+ using DotNetOpenAuth;
+ using DotNetOpenAuth.Messaging.Bindings;
using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.RelyingParty;
/// <summary>
/// A database-backed state store for OpenID relying parties.
/// </summary>
- public class RelyingPartyApplicationDbStore : NonceDbStore, IRelyingPartyApplicationStore {
+ public class RelyingPartyApplicationDbStore : NonceDbStore, IOpenIdApplicationStore {
/// <summary>
/// Initializes a new instance of the <see cref="RelyingPartyApplicationDbStore"/> class.
/// </summary>
public RelyingPartyApplicationDbStore() {
}
- #region IAssociationStore<Uri> Members
+ #region ICryptoStore Members
- /// <summary>
- /// Saves an <see cref="Association"/> for later recall.
- /// </summary>
- /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for providers).</param>
- /// <param name="association">The association to store.</param>
- /// <remarks>
- /// TODO: what should implementations do on association handle conflict?
- /// </remarks>
- public void StoreAssociation(Uri distinguishingFactor, Association association) {
+ public CryptoKey GetKey(string bucket, string handle) {
using (var dataContext = new TransactedDatabaseEntities(System.Data.IsolationLevel.ReadCommitted)) {
- var sharedAssociation = new OpenIdAssociation {
- DistinguishingFactor = distinguishingFactor.AbsoluteUri,
- AssociationHandle = association.Handle,
- ExpirationUtc = association.Expires,
- PrivateData = association.SerializePrivateData(),
- };
-
- dataContext.AddToOpenIdAssociations(sharedAssociation);
+ var associations = from assoc in dataContext.SymmetricCryptoKeys
+ where assoc.Bucket == bucket
+ where assoc.Handle == handle
+ where assoc.ExpirationUtc > DateTime.UtcNow
+ select assoc;
+ return associations.AsEnumerable()
+ .Select(assoc => new CryptoKey(assoc.Secret, assoc.ExpirationUtc.AsUtc()))
+ .FirstOrDefault();
}
}
- /// <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) {
+ public IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket) {
using (var dataContext = new TransactedDatabaseEntities(System.Data.IsolationLevel.ReadCommitted)) {
- var relevantAssociations = from assoc in dataContext.OpenIdAssociations
- where assoc.DistinguishingFactor == distinguishingFactor.AbsoluteUri
+ var relevantAssociations = from assoc in dataContext.SymmetricCryptoKeys
+ where assoc.Bucket == bucket
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();
+ .Select(assoc => new KeyValuePair<string, CryptoKey>(assoc.Handle, new CryptoKey(assoc.Secret, assoc.ExpirationUtc.AsUtc())));
+ return qualifyingAssociations.ToList(); // the data context is closing, so we must cache the result.
}
}
- /// <summary>
- /// Gets the association for a given key and handle.
- /// </summary>
- /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
- /// <param name="handle">The handle of the specific association that must be recalled.</param>
- /// <returns>
- /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key and handle.
- /// </returns>
- public Association GetAssociation(Uri distinguishingFactor, string handle) {
+ public void StoreKey(string bucket, string handle, CryptoKey key) {
using (var dataContext = new TransactedDatabaseEntities(System.Data.IsolationLevel.ReadCommitted)) {
- var associations = from assoc in dataContext.OpenIdAssociations
- where assoc.DistinguishingFactor == distinguishingFactor.AbsoluteUri
- where assoc.AssociationHandle == handle
- where assoc.ExpirationUtc > DateTime.UtcNow
- select assoc;
- return associations.AsEnumerable()
- .Select(assoc => DeserializeAssociation(assoc))
- .FirstOrDefault();
+ var sharedAssociation = new SymmetricCryptoKey {
+ Bucket = bucket,
+ Handle = handle,
+ ExpirationUtc = key.ExpiresUtc,
+ Secret = key.Key,
+ };
+
+ dataContext.AddToSymmetricCryptoKeys(sharedAssociation);
}
}
- /// <summary>
- /// Removes a specified handle that may exist in the store.
- /// </summary>
- /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
- /// <param name="handle">The handle of the specific association that must be deleted.</param>
- /// <returns>
- /// True if the association existed in this store previous to this call.
- /// </returns>
- /// <remarks>
- /// No exception should be thrown if the association does not exist in the store
- /// before this call.
- /// </remarks>
- public bool RemoveAssociation(Uri distinguishingFactor, string handle) {
+ public void RemoveKey(string bucket, string handle) {
using (var dataContext = new TransactedDatabaseEntities(System.Data.IsolationLevel.ReadCommitted)) {
- var association = dataContext.OpenIdAssociations.FirstOrDefault(a => a.DistinguishingFactor == distinguishingFactor.AbsoluteUri && a.AssociationHandle == handle);
+ var association = dataContext.SymmetricCryptoKeys.FirstOrDefault(a => a.Bucket == bucket && a.Handle == handle);
if (association != null) {
dataContext.DeleteObject(association);
- return true;
} else {
- return false;
}
}
}
+ #endregion
+
/// <summary>
/// Clears all expired associations from the store.
/// </summary>
@@ -132,27 +85,10 @@ namespace RelyingPartyLogic {
/// This should be done frequently enough to avoid a memory leak, but sparingly enough
/// to not be a performance drain.
/// </remarks>
- public void ClearExpiredAssociations() {
+ internal void ClearExpiredCryptoKeys() {
using (var dataContext = new TransactedDatabaseEntities(IsolationLevel.ReadCommitted)) {
- dataContext.ClearExpiredAssociations(dataContext.Transaction);
+ dataContext.ClearExpiredCryptoKeys(dataContext.Transaction);
}
}
-
- #endregion
-
- /// <summary>
- /// Deserializes an association from the database.
- /// </summary>
- /// <param name="association">The association from the database.</param>
- /// <returns>The deserialized association.</returns>
- private static Association DeserializeAssociation(OpenIdAssociation association) {
- if (association == null) {
- throw new ArgumentNullException("association");
- }
-
- byte[] privateData = new byte[association.PrivateDataLength];
- Array.Copy(association.PrivateData, privateData, association.PrivateDataLength);
- return Association.Deserialize(association.AssociationHandle, association.ExpirationUtc, privateData);
- }
}
}