SamlAssertion.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. //
  2. // SamlAssertion.cs
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. // Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Collections.Generic;
  30. using System.Globalization;
  31. using System.Xml;
  32. using System.IdentityModel.Selectors;
  33. namespace System.IdentityModel.Tokens
  34. {
  35. public class SamlAssertion
  36. {
  37. bool is_readonly;
  38. SamlAdvice advice;
  39. SamlConditions conditions;
  40. string assertion_id, issuer;
  41. DateTime issue_instant;
  42. int major, minor;
  43. SigningCredentials signing_credentials;
  44. List<SamlStatement> statements = new List<SamlStatement> ();
  45. public SamlAssertion ()
  46. {
  47. assertion_id = "SamlSecurityToken-" + Guid.NewGuid ();
  48. major = 1;
  49. minor = 1;
  50. issue_instant = DateTime.Now.ToUniversalTime ();
  51. }
  52. public SamlAssertion (string assertionId, string issuer,
  53. DateTime issueInstant, SamlConditions conditions,
  54. SamlAdvice advice, IEnumerable<SamlStatement> statements)
  55. {
  56. if (IsInvalidAssertionId (assertionId))
  57. throw new ArgumentException (String.Format ("The assertionId '{0}' must be a valid XML NCName.", assertionId));
  58. if (issuer == null || issuer.Length == 0)
  59. throw new ArgumentException ("issuer");
  60. if (statements == null)
  61. throw new ArgumentNullException ("statements");
  62. major = 1;
  63. minor = 1;
  64. assertion_id = assertionId;
  65. this.issuer = issuer;
  66. issue_instant = issueInstant;
  67. this.conditions = conditions;
  68. this.advice = advice;
  69. foreach (SamlStatement s in statements) {
  70. if (s == null)
  71. throw new ArgumentException ("statements contain null item.");
  72. this.statements.Add (s);
  73. }
  74. if (this.statements.Count == 0)
  75. throw new ArgumentException ("At least one assertion statement is required.");
  76. }
  77. bool IsInvalidAssertionId (string assertionId)
  78. {
  79. if (assertionId == null || assertionId.Length == 0)
  80. return true;
  81. try {
  82. XmlConvert.VerifyNCName (assertionId);
  83. } catch (XmlException) {
  84. return true;
  85. }
  86. return false;
  87. }
  88. public SamlAdvice Advice {
  89. get { return advice; }
  90. set {
  91. CheckReadOnly ();
  92. advice = value;
  93. }
  94. }
  95. public string AssertionId {
  96. get { return assertion_id; }
  97. set {
  98. CheckReadOnly ();
  99. assertion_id = value;
  100. }
  101. }
  102. public SamlConditions Conditions {
  103. get { return conditions; }
  104. set {
  105. CheckReadOnly ();
  106. conditions = value;
  107. }
  108. }
  109. public DateTime IssueInstant {
  110. get { return issue_instant; }
  111. set {
  112. CheckReadOnly ();
  113. issue_instant = value;
  114. }
  115. }
  116. public string Issuer {
  117. get { return issuer; }
  118. set {
  119. CheckReadOnly ();
  120. issuer = value;
  121. }
  122. }
  123. public int MajorVersion {
  124. get { return major; }
  125. }
  126. public int MinorVersion {
  127. get { return minor; }
  128. }
  129. public SigningCredentials SigningCredentials {
  130. get { return signing_credentials; }
  131. set {
  132. CheckReadOnly ();
  133. signing_credentials = value;
  134. }
  135. }
  136. [MonoTODO]
  137. public SecurityToken SigningToken {
  138. get {
  139. if (signing_credentials == null)
  140. return null;
  141. throw new NotImplementedException ();
  142. }
  143. }
  144. public IList<SamlStatement> Statements {
  145. get { return statements; }
  146. }
  147. public bool IsReadOnly {
  148. get { return is_readonly; }
  149. }
  150. private void CheckReadOnly ()
  151. {
  152. if (is_readonly)
  153. throw new InvalidOperationException ("This SAML assertion is read-only.");
  154. }
  155. public void MakeReadOnly ()
  156. {
  157. is_readonly = true;
  158. }
  159. [MonoTODO]
  160. public virtual void ReadXml (XmlDictionaryReader reader,
  161. SamlSerializer samlSerializer,
  162. SecurityTokenSerializer keyInfoTokenSerializer,
  163. SecurityTokenResolver outOfBandTokenResolver)
  164. {
  165. throw new NotImplementedException ();
  166. }
  167. public virtual void WriteXml (XmlDictionaryWriter writer,
  168. SamlSerializer samlSerializer,
  169. SecurityTokenSerializer keyInfoTokenSerializer)
  170. {
  171. if (writer == null)
  172. throw new ArgumentNullException ("writer");
  173. if (Issuer == null || Issuer.Length == 0)
  174. throw new SecurityTokenException ("Issuer must not be null or empty.");
  175. if (Statements.Count == 0)
  176. throw new SecurityTokenException ("At least one assertion statement is required.");
  177. if (samlSerializer == null)
  178. throw new ArgumentNullException ("samlSerializer");
  179. CultureInfo invariant = CultureInfo.InvariantCulture;
  180. writer.WriteStartElement ("saml", "Assertion", SamlConstants.Namespace);
  181. writer.WriteAttributeString ("MajorVersion", MajorVersion.ToString (invariant));
  182. writer.WriteAttributeString ("MinorVersion", MinorVersion.ToString (invariant));
  183. writer.WriteAttributeString ("AssertionID", AssertionId);
  184. writer.WriteAttributeString ("Issuer", Issuer);
  185. writer.WriteAttributeString ("IssueInstant", IssueInstant.ToString (SamlConstants.DateFormat, invariant));
  186. try {
  187. if (Conditions != null)
  188. Conditions.WriteXml (writer, samlSerializer, keyInfoTokenSerializer);
  189. if (Advice != null)
  190. Advice.WriteXml (writer, samlSerializer, keyInfoTokenSerializer);
  191. foreach (SamlStatement statement in Statements)
  192. statement.WriteXml (writer, samlSerializer, keyInfoTokenSerializer);
  193. } catch (NotImplementedException) {
  194. throw;
  195. } catch (Exception ex) { // bad catch, eh?
  196. throw new InvalidOperationException ("There is an error on writing assertion statements.", ex);
  197. }
  198. writer.WriteEndElement ();
  199. }
  200. [MonoTODO]
  201. protected void ReadSignature (XmlDictionaryReader reader,
  202. SecurityTokenSerializer keyInfoTokenSerializer,
  203. SecurityTokenResolver outOfBandTokenResolver,
  204. SamlSerializer samlSerializer)
  205. {
  206. throw new NotImplementedException ();
  207. }
  208. }
  209. }