Permalink
Browse files

NETC-4

Ensure .NET Framework 2.0 Compatibility
  • Loading branch information...
1 parent 4bda8f8 commit 517a5e6eba86186a7560e73c3da222a43e841065 @scottt732 scottt732 committed Dec 6, 2010
Showing with 7 additions and 268 deletions.
  1. +0 −151 DotNetCasClient/Validation/CasSaml11Response.cs
  2. +7 −117 DotNetCasClient/Validation/SamlUtils.cs
@@ -19,163 +19,13 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
using System.Xml;
using DotNetCasClient.Logging;
using DotNetCasClient.Security;
-using DotNetCasClient.Utils;
namespace DotNetCasClient.Validation
{
-#if DOT_NET_3
- /// <summary>
- /// Represents a CAS SAML 1.1 response from a CAS server, using
- /// SamlSecurityToken methods for parsing to populate the object.
- /// </summary>
- class CasSaml11Response : System.IdentityModel.Tokens.SamlSecurityToken
- {
- /// <summary>
- /// The SAML 1.1 Assertion namespace
- /// </summary>
- const string SAML11_ASSERTION_NAMESPACE = "urn:oasis:names:tc:SAML:1.0:assertion";
-
- private static readonly Logger protoLogger = new Logger(Category.Protocol);
-
- /// <summary>
- /// Tolerance ticks for checking the current time against the SAML
- /// Assertion valid times.
- /// </summary>
- private readonly long _ToleranceTicks = 1000L * TimeSpan.TicksPerMillisecond;
-
- // The raw response received from the CAS server
- private readonly string _CasResponse;
-
- // The assertion from the CAS server response used to populate this instance
- System.IdentityModel.Tokens.SamlAssertion _CasSamlAssertion;
-
- #region Properties
- /// <summary>
- /// Whether a valid SAML Assertion was found for processing
- /// </summary>
- public bool HasCasSamlAssertion { get; private set; }
-
- /// <summary>
- /// The JaSig CAS ICasPrincipal assertion built from the received CAS
- /// SAML 1.1 response
- /// </summary>
- public ICasPrincipal CasPrincipal { get; private set; }
- #endregion
-
- /// <summary>
- /// Creates a CasSaml11Response from the response returned by the CAS
- /// server. The SAMLAssertion processed is the first valid SAML Asssertion
- /// found in the server response.
- /// </summary>
- /// <param name="response">
- /// the xml for the SAML 1.1 response received in response to the
- /// samlValidate query to the CAS server
- /// </param>
- /// <param name="tolerance">
- /// Tolerance milliseconds for checking the current time against the SAML
- /// Assertion valid times.
- /// </param>
- public CasSaml11Response(string response, long tolerance)
- {
- _ToleranceTicks = tolerance * TimeSpan.TicksPerMillisecond;
- HasCasSamlAssertion = false;
- _CasResponse = response;
- ProcessValidAssertion();
- HasCasSamlAssertion = true;
-
- // Initialize the SamlSecurityToken with the SamlAssertion. Hopefully
- // this will be useful as the SAML support in .NET advances.
- Initialize(_CasSamlAssertion);
- }
-
- /// <summary>
- /// Initializes the CAS IAssertion for this instance from the first valid
- /// Assertion node in the CAS server response. First the Assertion node is
- /// identified and stored in this instance as a .NET SamlAssertion. This
- /// SamlAssertion is then used to create the Iassertion instance.
- /// </summary>
- /// <exception cref="TicketValidationException">
- /// Throwsn when data problems are encountered parsing
- /// the CAS server response that contains the Assertion, such as
- /// no valid Assertion found or no Authentication statment found in the
- /// the valid Assertion.
- /// </exception>
- private void ProcessValidAssertion()
- {
- protoLogger.Debug("Unmarshalling SAML response");
-
- XmlDocument document = new XmlDocument();
- document.Load(new StringReader(_CasResponse));
-
- XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
- nsmgr.AddNamespace("assertion", SAML11_ASSERTION_NAMESPACE);
- if (document.DocumentElement != null)
- {
- XmlNodeList assertions = document.DocumentElement.SelectNodes("descendant::assertion:Assertion", nsmgr);
- if (assertions == null || assertions.Count < 1)
- {
- throw new TicketValidationException("No assertions found.");
- }
-
- XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
- xmlReaderSettings.IgnoreWhitespace = true;
- xmlReaderSettings.IgnoreComments = true;
- xmlReaderSettings.CloseInput = true;
-
- foreach (XmlNode assertionNode in assertions)
- {
- XmlTextReader xmlReader = new XmlTextReader(new StringReader(assertionNode.OuterXml));
- XmlDictionaryReader xmlDicReader = XmlDictionaryReader.CreateDictionaryReader(xmlReader);
- System.IdentityModel.Tokens.SamlSerializer samlSerializer = new System.IdentityModel.Tokens.SamlSerializer();
- System.IdentityModel.Selectors.SecurityTokenSerializer keyInfoSerializer = null;
- System.IdentityModel.Selectors.SecurityTokenResolver outOfBandTokenResolver = null;
- System.IdentityModel.Tokens.SamlAssertion assertion = samlSerializer.LoadAssertion(xmlDicReader, keyInfoSerializer, outOfBandTokenResolver);
-
- if (!SamlUtils.IsValidAssertion(assertion, _ToleranceTicks))
- {
- continue;
- }
-
- System.IdentityModel.Tokens.SamlAuthenticationStatement authenticationStatement = SamlUtils.GetSAMLAuthenticationStatement(assertion);
- if (authenticationStatement == null)
- {
- throw new TicketValidationException("No AuthenticationStatement found in the CAS response.");
- }
-
- System.IdentityModel.Tokens.SamlSubject subject = authenticationStatement.SamlSubject;
- if (subject == null)
- {
- throw new TicketValidationException("No Subject found in the CAS response.");
- }
-
- _CasSamlAssertion = assertion;
- IList<System.IdentityModel.Tokens.SamlAttribute> attributes = SamlUtils.GetAttributesFor(_CasSamlAssertion, subject);
- IDictionary<string, IList<string>> personAttributes = new Dictionary<string, IList<string>>();
- foreach (System.IdentityModel.Tokens.SamlAttribute samlAttribute in attributes)
- {
- IList<string> values = SamlUtils.GetValuesFor(samlAttribute);
- personAttributes.Add(samlAttribute.Name, values);
- }
-
- IDictionary<string, IList<string>> authenticationAttributes = new Dictionary<string, IList<string>>();
- IList<string> authValues = new List<string>();
- authValues.Add(authenticationStatement.AuthenticationMethod);
- authenticationAttributes.Add("samlAuthenticationStatement::authMethod", authValues);
- IAssertion casAssertion = new Assertion(subject.Name, _CasSamlAssertion.Conditions.NotBefore, _CasSamlAssertion.Conditions.NotOnOrAfter, personAttributes);
-
- CasPrincipal = new CasPrincipal(casAssertion, null);
- return;
- }
- }
- throw new TicketValidationException("No valid assertions found in the CAS response.");
- }
- }
-#else
/// <summary>
/// Represents a CAS SAML 1.1 response from a CAS server, using Xml parsing to
/// populate the object.
@@ -330,5 +180,4 @@ private void ProcessValidAssertion()
}
#endregion
}
-#endif
}
@@ -19,10 +19,8 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Xml;
using DotNetCasClient.Logging;
-using DotNetCasClient.Utils;
namespace DotNetCasClient.Validation
{
@@ -32,117 +30,9 @@ namespace DotNetCasClient.Validation
/// </summary>
internal static class SamlUtils
{
- private static readonly Logger protoLogger = new Logger(Category.Protocol);
-#if DOT_NET_3
- /// <summary>
- /// Determines whether the SAML Assertion is valid in terms of the
- /// 'not before' and the 'not on or after' times.
- /// </summary>
- /// <param name="assertion">the SAML Assertion to be checked</param>
- /// <param name="toleranceTicks">
- /// Tolerance ticks for checking the current time against the SAML Assertion
- /// valid times.
- /// </param>
- /// <returns>
- /// true if this Assertion is valid relative to the current time; otherwise
- /// returns false
- /// </returns>
- public static bool IsValidAssertion(System.IdentityModel.Tokens.SamlAssertion assertion, long toleranceTicks)
- {
- DateTime notBefore = assertion.Conditions.NotBefore;
- DateTime notOnOrAfter = assertion.Conditions.NotOnOrAfter;
-
- return IsValidAssertion(notBefore, notOnOrAfter, toleranceTicks);
- }
-
+ private static readonly Logger ProtoLogger = new Logger(Category.Protocol);
/// <summary>
- /// Populates an IList with the Values from a SAML Attribute.
- /// </summary>
- /// <param name="attribute">the SAML Attribute to be parsed</param>
- /// <returns>
- /// the IList of existing values, which will be an empty List if no
- /// values are found
- /// </returns>
- public static IList<string> GetValuesFor(System.IdentityModel.Tokens.SamlAttribute attribute)
- {
- IList<string> values = new List<string>();
- foreach (string value in attribute.AttributeValues)
- {
- values.Add(value);
- }
- return values;
- }
-
-
- /// <summary>
- /// Retrieves the Authentication Statement from a SAML Assertion.
- /// </summary>
- /// <param name="assertion">the SAML Assertion to be parsed</param>
- /// <returns>
- /// the Authentication Statement for this Assertion if one exists; otherwise
- /// returns null.
- /// </returns>
- public static System.IdentityModel.Tokens.SamlAuthenticationStatement GetSAMLAuthenticationStatement(System.IdentityModel.Tokens.SamlAssertion assertion)
- {
- IEnumerable<System.IdentityModel.Tokens.SamlStatement> samlStmtEnum = assertion.Statements;
- Type targetTypeAuth = typeof(System.IdentityModel.Tokens.SamlAuthenticationStatement);
-
- int stmtCount = 0;
- foreach (Object obj in samlStmtEnum)
- {
- stmtCount++;
- System.IdentityModel.Tokens.SamlStatement nextStmt = (System.IdentityModel.Tokens.SamlStatement) obj;
- if (nextStmt.GetType().Equals(targetTypeAuth))
- {
- return (System.IdentityModel.Tokens.SamlAuthenticationStatement) nextStmt;
- }
- }
-
- return null;
- }
-
- /// <summary>
- /// Populates an IList with the Attributes from the SAML Assertion for the
- /// given SAML subject.
- /// </summary>
- /// <param name="assertion">the SAML Assertion to be parsed</param>
- /// <param name="subject">
- /// the SAML Subject for which Attributes are to be retrieved
- /// </param>
- /// <returns>
- /// the IList of matching attributes, which will be an empty List if no
- /// matches are found
- /// </returns>
- public static IList<System.IdentityModel.Tokens.SamlAttribute> GetAttributesFor(System.IdentityModel.Tokens.SamlAssertion assertion, System.IdentityModel.Tokens.SamlSubject subject)
- {
- IList<System.IdentityModel.Tokens.SamlAttribute> attributes = new List<System.IdentityModel.Tokens.SamlAttribute>();
- IEnumerable<System.IdentityModel.Tokens.SamlStatement> samlStmtEnum = assertion.Statements;
- Type targetTypeAttr = typeof(System.IdentityModel.Tokens.SamlAttributeStatement);
-
- foreach (Object obj in samlStmtEnum)
- {
- System.IdentityModel.Tokens.SamlStatement nextStmt = (System.IdentityModel.Tokens.SamlStatement)obj;
- if (nextStmt.GetType().Equals(targetTypeAttr))
- {
- System.IdentityModel.Tokens.SamlAttributeStatement attributeStatement = (System.IdentityModel.Tokens.SamlAttributeStatement) nextStmt;
- if (!(subject.Equals(attributeStatement.SamlSubject) || subject.Name.Equals(attributeStatement.SamlSubject.Name)))
- {
- continue;
- }
-
- // Found attributes for this Subject. Transfer them to List.
- foreach (System.IdentityModel.Tokens.SamlAttribute nextAttr in attributeStatement.Attributes)
- {
- attributes.Add(nextAttr);
- }
- }
- }
-
- return attributes;
- }
-#endif
- /// <summary>
/// Determines whether the SAML Assertion is valid in terms of the
/// 'not before' and the 'not on or after' times.
/// </summary>
@@ -164,21 +54,21 @@ public static bool IsValidAssertion(DateTime notBefore, DateTime notOnOrAfter, l
{
if (notBefore == DateTime.MinValue || notOnOrAfter == DateTime.MinValue)
{
- protoLogger.Debug("Assertion has no bounding dates. Will not process.");
+ ProtoLogger.Debug("Assertion has no bounding dates. Will not process.");
return false;
}
- protoLogger.Debug("Assertion validity window: {0} - {1} +/- {2}ms", notBefore, notOnOrAfter, toleranceTicks / 10000);
+ ProtoLogger.Debug("Assertion validity window: {0} - {1} +/- {2}ms", notBefore, notOnOrAfter, toleranceTicks / 10000);
long utcNowTicks = DateTime.UtcNow.Ticks;
if (utcNowTicks + toleranceTicks < notBefore.Ticks)
{
- protoLogger.Debug("Assertion is not yet valid.");
+ ProtoLogger.Debug("Assertion is not yet valid.");
return false;
}
if (notOnOrAfter.Ticks <= utcNowTicks - toleranceTicks)
{
- protoLogger.Debug("Assertion is expired.");
+ ProtoLogger.Debug("Assertion is expired.");
return false;
}
@@ -214,7 +104,7 @@ public static bool IsValidAssertion(DateTime notBefore, DateTime notOnOrAfter, l
XmlNode nameIdentifierNode = attributeStmtNode.SelectSingleNode("child::assertion:Subject/child::assertion:NameIdentifier", nsmgr);
if (nameIdentifierNode == null)
{
- protoLogger.Debug("No NameIdentifier found in SAML response");
+ ProtoLogger.Debug("No NameIdentifier found in SAML response");
throw new TicketValidationException("No NameIdentifier found in AttributeStatement of the CAS response.");
}
@@ -223,7 +113,7 @@ public static bool IsValidAssertion(DateTime notBefore, DateTime notOnOrAfter, l
{
string message = string.Format("Subject ({0}) does not match requested subject ({1}) in the CAS response.",
subject, subjectName);
- protoLogger.Debug(message);
+ ProtoLogger.Debug(message);
throw new TicketValidationException(message);
}

0 comments on commit 517a5e6

Please sign in to comment.