summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-04-09 22:06:03 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2009-04-09 22:06:03 -0700
commit82781e309db03f8afd09629f2b1bbce10fa355c5 (patch)
tree78aab6080a65b4740ece9aa1382503a8f718da87
parent5d58ebb1186351deba062b3309fcc4a69465b984 (diff)
downloadDotNetOpenAuth-82781e309db03f8afd09629f2b1bbce10fa355c5.zip
DotNetOpenAuth-82781e309db03f8afd09629f2b1bbce10fa355c5.tar.gz
DotNetOpenAuth-82781e309db03f8afd09629f2b1bbce10fa355c5.tar.bz2
Refactored the programmatic interface of InfoCard token parsing.
-rw-r--r--src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs10
-rw-r--r--src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs42
-rw-r--r--src/DotNetOpenAuth/InfoCard/Token/Token.cs60
-rw-r--r--src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs10
4 files changed, 98 insertions, 24 deletions
diff --git a/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs b/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
index 48f0100..b787300 100644
--- a/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
+++ b/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
@@ -387,12 +387,11 @@ namespace DotNetOpenAuth.InfoCard {
if (!string.IsNullOrEmpty(this.TokenXml)) {
try {
bool encrypted = Token.IsEncrypted(this.TokenXml);
- TokenDecryptor decryptor = encrypted ? new TokenDecryptor() : null;
- ReceivingTokenEventArgs receivingArgs = this.OnReceivingToken(this.TokenXml, decryptor);
+ ReceivingTokenEventArgs receivingArgs = this.OnReceivingToken(this.TokenXml);
if (!receivingArgs.Cancel) {
try {
- Token token = new Token(this.TokenXml, this.Audience, decryptor);
+ Token token = Token.Read(this.TokenXml, this.Audience, receivingArgs.DecryptingTokens);
this.OnReceivedToken(token);
} catch (InformationCardException ex) {
this.OnTokenProcessingError(this.TokenXml, ex);
@@ -408,14 +407,13 @@ namespace DotNetOpenAuth.InfoCard {
/// Fires the <see cref="ReceivingToken"/> event.
/// </summary>
/// <param name="tokenXml">The token XML, prior to any processing.</param>
- /// <param name="decryptor">The decryptor to use, if the token is encrypted.</param>
/// <returns>The event arguments sent to the event handlers.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "decryptor", Justification = "By design")]
- protected virtual ReceivingTokenEventArgs OnReceivingToken(string tokenXml, TokenDecryptor decryptor) {
+ protected virtual ReceivingTokenEventArgs OnReceivingToken(string tokenXml) {
Contract.Requires(tokenXml != null);
ErrorUtilities.VerifyArgumentNotNull(tokenXml, "tokenXml");
- var args = new ReceivingTokenEventArgs(tokenXml, decryptor);
+ var args = new ReceivingTokenEventArgs(tokenXml);
var receivingToken = this.ReceivingToken;
if (receivingToken != null) {
receivingToken(this, args);
diff --git a/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs b/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs
index 004d134..f3722d7 100644
--- a/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs
+++ b/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs
@@ -6,8 +6,11 @@
namespace DotNetOpenAuth.InfoCard {
using System;
+ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
+ using System.IdentityModel.Tokens;
+ using System.Security.Cryptography.X509Certificates;
/// <summary>
/// Arguments for the <see cref="InfoCardSelector.ReceivingToken"/> event.
@@ -17,13 +20,12 @@ namespace DotNetOpenAuth.InfoCard {
/// Initializes a new instance of the <see cref="ReceivingTokenEventArgs"/> class.
/// </summary>
/// <param name="tokenXml">The raw token XML, prior to any decryption.</param>
- /// <param name="decryptor">The decryptor to use if the token is encrypted.</param>
- internal ReceivingTokenEventArgs(string tokenXml, TokenDecryptor decryptor) {
+ internal ReceivingTokenEventArgs(string tokenXml) {
Contract.Requires(tokenXml != null);
this.TokenXml = tokenXml;
this.IsEncrypted = Token.IsEncrypted(this.TokenXml);
- this.Decryptor = decryptor;
+ this.DecryptingTokens = new List<SecurityToken>();
}
/// <summary>
@@ -40,13 +42,6 @@ namespace DotNetOpenAuth.InfoCard {
public string TokenXml { get; private set; }
/// <summary>
- /// Gets the object that will perform token decryption, if necessary.
- /// </summary>
- /// <value>The decryptor to use; or <c>null</c> if the token is not encrypted.</value>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Decryptor", Justification = "By design")]
- public TokenDecryptor Decryptor { get; private set; }
-
- /// <summary>
/// Gets or sets a value indicating whether processing
/// this token should be canceled.
/// </summary>
@@ -57,6 +52,31 @@ namespace DotNetOpenAuth.InfoCard {
/// </remarks>
public bool Cancel { get; set; }
+ /// <summary>
+ /// Gets a list where security tokens such as X.509 certificates may be
+ /// added to be used for token decryption.
+ /// </summary>
+ internal IList<SecurityToken> DecryptingTokens { get; private set; }
+
+ /// <summary>
+ /// Adds a security token that may be used to decrypt the incoming token.
+ /// </summary>
+ /// <param name="securityToken">The security token.</param>
+ public void AddDecryptingToken(SecurityToken securityToken) {
+ Contract.Requires(securityToken != null);
+ this.DecryptingTokens.Add(securityToken);
+ }
+
+ /// <summary>
+ /// Adds an X.509 certificate with a private key that may be used to decrypt the incoming token.
+ /// </summary>
+ /// <param name="certificate">The certificate.</param>
+ public void AddDecryptingToken(X509Certificate2 certificate) {
+ Contract.Requires(certificate != null);
+ Contract.Requires(certificate.HasPrivateKey);
+ this.AddDecryptingToken(new X509SecurityToken(certificate));
+ }
+
#if CONTRACTS_FULL
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
@@ -65,7 +85,7 @@ namespace DotNetOpenAuth.InfoCard {
[ContractInvariantMethod]
protected void ObjectInvariant() {
Contract.Invariant(this.TokenXml != null);
- Contract.Invariant((this.Decryptor != null) == this.IsEncrypted);
+ Contract.Invariant(this.DecryptingTokens != null);
}
#endif
}
diff --git a/src/DotNetOpenAuth/InfoCard/Token/Token.cs b/src/DotNetOpenAuth/InfoCard/Token/Token.cs
index d72b47a..f07c555 100644
--- a/src/DotNetOpenAuth/InfoCard/Token/Token.cs
+++ b/src/DotNetOpenAuth/InfoCard/Token/Token.cs
@@ -11,8 +11,9 @@ namespace DotNetOpenAuth.InfoCard {
using System.Diagnostics.Contracts;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
+ using System.IdentityModel.Tokens;
using System.IO;
- using System.Security.Cryptography.X509Certificates;
+ using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
@@ -40,7 +41,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="audience">The audience. May be <c>null</c> to avoid audience checking.</param>
/// <param name="decryptor">The decryptor to use to decrypt the token, if necessary..</param>
/// <exception cref="InformationCardException">Thrown for any problem decoding or decrypting the token.</exception>
- internal Token(string tokenXml, Uri audience, TokenDecryptor decryptor) {
+ private Token(string tokenXml, Uri audience, TokenDecryptor decryptor) {
Contract.Requires(tokenXml != null && tokenXml.Length > 0);
Contract.Requires(decryptor != null || !IsEncrypted(tokenXml));
ErrorUtilities.VerifyNonZeroLength(tokenXml, "tokenXml");
@@ -125,6 +126,61 @@ namespace DotNetOpenAuth.InfoCard {
}
/// <summary>
+ /// Deserializes an XML document into a token.
+ /// </summary>
+ /// <param name="tokenXml">The token XML.</param>
+ /// <returns>The deserialized token.</returns>
+ public static Token Read(string tokenXml) {
+ Contract.Requires(!String.IsNullOrEmpty(tokenXml));
+ return Read(tokenXml, (Uri)null);
+ }
+
+ /// <summary>
+ /// Deserializes an XML document into a token.
+ /// </summary>
+ /// <param name="tokenXml">The token XML.</param>
+ /// <param name="audience">The URI that this token must have been crafted to be sent to. Use <c>null</c> to accept any intended audience.</param>
+ /// <returns>The deserialized token.</returns>
+ public static Token Read(string tokenXml, Uri audience) {
+ Contract.Requires(!String.IsNullOrEmpty(tokenXml));
+ return Read(tokenXml, audience, Enumerable.Empty<SecurityToken>());
+ }
+
+ /// <summary>
+ /// Deserializes an XML document into a token.
+ /// </summary>
+ /// <param name="tokenXml">The token XML.</param>
+ /// <param name="decryptionTokens">Any X.509 certificates that may be used to decrypt the token, if necessary.</param>
+ /// <returns>The deserialized token.</returns>
+ public static Token Read(string tokenXml, IEnumerable<SecurityToken> decryptionTokens) {
+ Contract.Requires(!String.IsNullOrEmpty(tokenXml));
+ Contract.Requires(decryptionTokens != null);
+ return Read(tokenXml, null, decryptionTokens);
+ }
+
+ /// <summary>
+ /// Deserializes an XML document into a token.
+ /// </summary>
+ /// <param name="tokenXml">The token XML.</param>
+ /// <param name="audience">The URI that this token must have been crafted to be sent to. Use <c>null</c> to accept any intended audience.</param>
+ /// <param name="decryptionTokens">Any X.509 certificates that may be used to decrypt the token, if necessary.</param>
+ /// <returns>The deserialized token.</returns>
+ public static Token Read(string tokenXml, Uri audience, IEnumerable<SecurityToken> decryptionTokens) {
+ Contract.Requires(!String.IsNullOrEmpty(tokenXml));
+ Contract.Requires(decryptionTokens != null);
+ Contract.Ensures(Contract.Result<Token>() != null);
+
+ TokenDecryptor decryptor = null;
+
+ if (IsEncrypted(tokenXml)) {
+ decryptor = new TokenDecryptor();
+ decryptor.Tokens.AddRange(decryptionTokens);
+ }
+
+ return new Token(tokenXml, audience, decryptor);
+ }
+
+ /// <summary>
/// Determines whether the specified token XML is encrypted.
/// </summary>
/// <param name="tokenXml">The token XML.</param>
diff --git a/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs b/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs
index 5d1be94..1038ad7 100644
--- a/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs
+++ b/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs
@@ -27,7 +27,7 @@ namespace DotNetOpenAuth.InfoCard {
/// A utility class for decrypting InfoCard tokens.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Decryptor", Justification = "By design")]
- public class TokenDecryptor {
+ internal class TokenDecryptor {
/// <summary>
/// Backing field for the <see cref="Tokens"/> property.
/// </summary>
@@ -49,7 +49,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <remarks>
/// Defaults to localmachine:my (same place SSL certs are)
/// </remarks>
- public IList<SecurityToken> Tokens {
+ internal List<SecurityToken> Tokens {
get { return this.tokens; }
}
@@ -57,7 +57,7 @@ namespace DotNetOpenAuth.InfoCard {
/// Adds a certificate to the list of certificates to decrypt with.
/// </summary>
/// <param name="certificate">The x509 cert to use for decryption</param>
- public void AddDecryptionCertificate(X509Certificate2 certificate) {
+ internal void AddDecryptionCertificate(X509Certificate2 certificate) {
this.Tokens.Add(new X509SecurityToken(certificate));
}
@@ -67,7 +67,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="storeName">store name of the certificate</param>
/// <param name="storeLocation">store location</param>
/// <param name="thumbprint">thumbprint of the cert to use</param>
- public void AddDecryptionCertificate(StoreName storeName, StoreLocation storeLocation, string thumbprint) {
+ internal void AddDecryptionCertificate(StoreName storeName, StoreLocation storeLocation, string thumbprint) {
this.AddDecryptionCertificates(
storeName,
storeLocation,
@@ -79,7 +79,7 @@ namespace DotNetOpenAuth.InfoCard {
/// </summary>
/// <param name="storeName">store name of the certificates</param>
/// <param name="storeLocation">store location</param>
- public void AddDecryptionCertificates(StoreName storeName, StoreLocation storeLocation) {
+ internal void AddDecryptionCertificates(StoreName storeName, StoreLocation storeLocation) {
this.AddDecryptionCertificates(storeName, storeLocation, store => store);
}