コード例 #1
0
		/// <summary>
		/// Stores a given nonce and timestamp.
		/// </summary>
		/// <param name="context">The context, or namespace, within which the <paramref name="nonce"/> must be unique.</param>
		/// <param name="nonce">A series of random characters.</param>
		/// <param name="timestamp">The timestamp that together with the nonce string make it unique.
		/// The timestamp may also be used by the data store to clear out old nonces.</param>
		/// <returns>
		/// True if the nonce+timestamp (combination) was not previously in the database.
		/// False if the nonce was stored previously with the same timestamp.
		/// </returns>
		/// <remarks>
		/// The nonce must be stored for no less than the maximum time window a message may
		/// be processed within before being discarded as an expired message.
		/// If the binding element is applicable to your channel, this expiration window
		/// is retrieved or set using the
		/// <see cref="StandardExpirationBindingElement.MaximumMessageAge"/> property.
		/// </remarks>
		public bool StoreNonce(string context, string nonce, DateTime timestamp) {
			if (timestamp.ToUniversalTimeSafe() + this.maximumMessageAge < DateTime.UtcNow) {
				// The expiration binding element should have taken care of this, but perhaps
				// it's at the boundary case.  We should fail just to be safe.
				return false;
			}

			// We just concatenate the context with the nonce to form a complete, namespace-protected nonce.
			string completeNonce = context + "\0" + nonce;

			lock (this.nonceLock) {
				List<string> nonces;
				if (!this.usedNonces.TryGetValue(timestamp, out nonces)) {
					this.usedNonces[timestamp] = nonces = new List<string>(4);
				}

				if (nonces.Contains(completeNonce)) {
					return false;
				}

				nonces.Add(completeNonce);

				// Clear expired nonces if it's time to take a moment to do that.
				// Unchecked so that this can int overflow without an exception.
				unchecked {
					this.nonceClearingCounter++;
				}
				if (this.nonceClearingCounter % AutoCleaningFrequency == 0) {
					this.ClearExpiredNonces();
				}

				return true;
			}
		}
コード例 #2
0
		/// <summary>
		/// Re-instantiates an <see cref="Association"/> previously persisted in a database or some
		/// other shared store.
		/// </summary>
		/// <param name="handle">
		/// The <see cref="Handle"/> property of the previous <see cref="Association"/> instance.
		/// </param>
		/// <param name="expiresUtc">
		/// The UTC value of the <see cref="Expires"/> property of the previous <see cref="Association"/> instance.
		/// </param>
		/// <param name="privateData">
		/// The byte array returned by a call to <see cref="SerializePrivateData"/> on the previous
		/// <see cref="Association"/> instance.
		/// </param>
		/// <returns>
		/// The newly dehydrated <see cref="Association"/>, which can be returned
		/// from a custom association store's 
		/// IRelyingPartyAssociationStore.GetAssociation method.
		/// </returns>
		public static Association Deserialize(string handle, DateTime expiresUtc, byte[] privateData) {
			Requires.NotNullOrEmpty(handle, "handle");
			Requires.NotNull(privateData, "privateData");
			Contract.Ensures(Contract.Result<Association>() != null);

			expiresUtc = expiresUtc.ToUniversalTimeSafe();
			TimeSpan remainingLifeLength = expiresUtc - DateTime.UtcNow;
			byte[] secret = privateData; // the whole of privateData is the secret key for now.
			// We figure out what derived type to instantiate based on the length of the secret.
			try {
				return HmacShaAssociation.Create(handle, secret, remainingLifeLength);
			} catch (ArgumentException ex) {
				throw new ArgumentException(OpenIdStrings.BadAssociationPrivateData, "privateData", ex);
			}
		}
コード例 #3
0
ファイル: Association.cs プロジェクト: jcp-xx/dotnetopenid
 /// <summary>
 /// Re-instantiates an <see cref="Association"/> previously persisted in a database or some
 /// other shared store.
 /// </summary>
 /// <param name="handle">
 /// The <see cref="Handle"/> property of the previous <see cref="Association"/> instance.
 /// </param>
 /// <param name="expires">
 /// The value of the <see cref="Expires"/> property of the previous <see cref="Association"/> instance.
 /// </param>
 /// <param name="privateData">
 /// The byte array returned by a call to <see cref="SerializePrivateData"/> on the previous
 /// <see cref="Association"/> instance.
 /// </param>
 /// <returns>
 /// The newly dehydrated <see cref="Association"/>, which can be returned
 /// from a custom association store's 
 /// <see cref="IAssociationStore&lt;TKey&gt;.GetAssociation(TKey, SecuritySettings)"/> method.
 /// </returns>
 public static Association Deserialize(string handle, DateTime expires, byte[] privateData)
 {
     if (string.IsNullOrEmpty(handle)) {
         throw new ArgumentNullException("handle");
     }
     if (privateData == null) {
         throw new ArgumentNullException("privateData");
     }
     expires = expires.ToUniversalTimeSafe();
     TimeSpan remainingLifeLength = expires - DateTime.UtcNow;
     byte[] secret = privateData; // the whole of privateData is the secret key for now.
     // We figure out what derived type to instantiate based on the length of the secret.
     try {
         return HmacShaAssociation.Create(handle, secret, remainingLifeLength);
     } catch (ArgumentException ex) {
         throw new ArgumentException(OpenIdStrings.BadAssociationPrivateData, "privateData", ex);
     }
 }