2 // BootstrapContextTest.cs - NUnit Test Cases for System.IdentityModel.Tokens.BootstrapContext
7 using System.IdentityModel.Tokens;
8 using System.Runtime.Serialization;
9 using System.Runtime.Serialization.Formatters.Binary;
12 using NUnit.Framework;
14 namespace MonoTests.System.IdentityModel.Tokens.net_4_5 {
16 public class BootstrapContextTest {
17 // The following byte arrays are the serialized bytes as emitted on Microsoft .Net 4.5.
18 private static readonly byte [] SerializedBootstrapContextByteArray = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x07, 0x03, 0x02, 0x02, 0x00, 0x00, 0x00, 0x42, 0x09, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x0B };
19 private static readonly byte [] SerializedBootstrapContextString = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x53, 0x06, 0x03, 0x00, 0x00, 0x00, 0x05, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x0B };
21 // Put in some non-ascii/latin1 characters to test the encoding scheme
22 // \u018E == Latin capital letter Reversed E
23 private const string user = "us\u018Er";
24 // \u00BD == Vulgar Fraction one half
25 private const string password = "pass\u00BDword";
26 private static readonly string SerializedBootstrapContextSecurityTokenString = "<UserNameSecurityToken Id=\"uuid-927c0b98-ba18-49d2-a653-306d60f85751-3\" Username=\"" + user + "\" Password=\"" + password + "\"/>";
27 private static readonly byte [] SerializedBootstrapContextSecurityToken = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x54, 0x06, 0x03, 0x00, 0x00, 0x00, 0x98, 0x01, 0x50, 0x46, 0x56, 0x7A, 0x5A, 0x58, 0x4A, 0x4F, 0x59, 0x57, 0x31, 0x6C, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x64, 0x48, 0x6C, 0x55, 0x62, 0x32, 0x74, 0x6C, 0x62, 0x69, 0x42, 0x4A, 0x5A, 0x44, 0x30, 0x69, 0x64, 0x58, 0x56, 0x70, 0x5A, 0x43, 0x30, 0x35, 0x4D, 0x6A, 0x64, 0x6A, 0x4D, 0x47, 0x49, 0x35, 0x4F, 0x43, 0x31, 0x69, 0x59, 0x54, 0x45, 0x34, 0x4C, 0x54, 0x51, 0x35, 0x5A, 0x44, 0x49, 0x74, 0x59, 0x54, 0x59, 0x31, 0x4D, 0x79, 0x30, 0x7A, 0x4D, 0x44, 0x5A, 0x6B, 0x4E, 0x6A, 0x42, 0x6D, 0x4F, 0x44, 0x55, 0x33, 0x4E, 0x54, 0x45, 0x74, 0x4D, 0x79, 0x49, 0x67, 0x56, 0x58, 0x4E, 0x6C, 0x63, 0x6D, 0x35, 0x68, 0x62, 0x57, 0x55, 0x39, 0x49, 0x6E, 0x56, 0x7A, 0x78, 0x6F, 0x35, 0x79, 0x49, 0x69, 0x42, 0x51, 0x59, 0x58, 0x4E, 0x7A, 0x64, 0x32, 0x39, 0x79, 0x5A, 0x44, 0x30, 0x69, 0x63, 0x47, 0x46, 0x7A, 0x63, 0x38, 0x4B, 0x39, 0x64, 0x32, 0x39, 0x79, 0x5A, 0x43, 0x49, 0x76, 0x50, 0x67, 0x3D, 0x3D, 0x0B };
30 public void Ctor_StringToken_Works ()
32 BootstrapContext bootstrapContext = new BootstrapContext ("token");
34 Assert.AreEqual ("token", bootstrapContext.Token, "#1");
35 Assert.IsNull (bootstrapContext.TokenBytes, "#2");
36 Assert.IsNull (bootstrapContext.SecurityToken, "#3");
37 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#4");
40 [ExpectedException (typeof (ArgumentNullException))]
41 public void Ctor_StringToken_NullToken_Throws ()
43 BootstrapContext bootstrapContext = new BootstrapContext ((string)null);
44 Assert.Fail ("Should have thrown");
48 public void Serialize_StringToken_Works ()
50 BootstrapContext bootstrapContext = new BootstrapContext ("token");
51 BinaryFormatter binaryFormatter = new BinaryFormatter ();
52 using (var s = new MemoryStream ()) {
53 binaryFormatter.Serialize (s, bootstrapContext);
55 BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext;
56 Assert.IsNotNull (bootstrapContext2, "#1");
57 Assert.AreEqual (bootstrapContext.Token, bootstrapContext2.Token, "#2");
58 Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3");
59 Assert.AreEqual (bootstrapContext.SecurityToken, bootstrapContext2.SecurityToken, "#4");
60 Assert.AreEqual (bootstrapContext.SecurityTokenHandler, bootstrapContext2.SecurityTokenHandler, "#5");
65 public void Deserialize_StringToken_Works ()
67 BinaryFormatter binaryFormatter = new BinaryFormatter ();
68 using (var s = new MemoryStream (SerializedBootstrapContextString)) {
69 BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext;
70 Assert.IsNotNull (bootstrapContext, "#1");
71 Assert.AreEqual ("token", bootstrapContext.Token, "#2");
72 Assert.IsNull (bootstrapContext.TokenBytes, "#3");
73 Assert.IsNull (bootstrapContext.SecurityToken, "#4");
74 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#5");
79 public void Ctor_ByteArrayToken_Works ()
81 BootstrapContext bootstrapContext = new BootstrapContext (new byte [] { 0x01 });
83 Assert.IsNotNull (bootstrapContext.TokenBytes, "#1");
84 Assert.AreEqual (1, bootstrapContext.TokenBytes.Length, "#2");
85 Assert.AreEqual (1, bootstrapContext.TokenBytes [0], "#3");
86 Assert.IsNull (bootstrapContext.Token, "#4");
87 Assert.IsNull (bootstrapContext.SecurityToken, "#5");
88 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#6");
92 [ExpectedException (typeof (ArgumentNullException))]
93 public void Ctor_ByteArrayToken_NullToken_Throws ()
95 BootstrapContext bootstrapContext = new BootstrapContext ((byte [])null);
96 Assert.Fail ("Should have thrown");
100 public void Serialize_ByteArrayToken_Works ()
102 BootstrapContext bootstrapContext = new BootstrapContext (new byte [] { 0x1 });
103 BinaryFormatter binaryFormatter = new BinaryFormatter ();
104 using (var s = new MemoryStream ()) {
105 binaryFormatter.Serialize (s, bootstrapContext);
107 BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext;
108 Assert.IsNotNull (bootstrapContext2, "#1");
109 Assert.AreEqual (bootstrapContext.Token, bootstrapContext2.Token, "#2");
110 Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3");
111 Assert.AreEqual (bootstrapContext.SecurityToken, bootstrapContext2.SecurityToken, "#4");
112 Assert.AreEqual (bootstrapContext.SecurityTokenHandler, bootstrapContext2.SecurityTokenHandler, "#5");
117 public void Deserialize_ByteArrayToken_Works ()
119 BinaryFormatter binaryFormatter = new BinaryFormatter ();
120 using (var s = new MemoryStream (SerializedBootstrapContextByteArray)) {
121 BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext;
122 Assert.IsNotNull (bootstrapContext, "#1");
123 Assert.IsNotNull (bootstrapContext.TokenBytes, "#2");
124 Assert.AreEqual (1, bootstrapContext.TokenBytes.Length, "#3");
125 Assert.AreEqual (1, bootstrapContext.TokenBytes [0], "#4");
126 Assert.IsNull (bootstrapContext.Token, "#5");
127 Assert.IsNull (bootstrapContext.SecurityToken, "#6");
128 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#7");
133 public void Ctor_SecurityToken_Works ()
135 var securityToken = new UserNameSecurityToken (user, password);
136 var securityTokenHandler = new SimpleSecurityTokenHandler ();
137 BootstrapContext bootstrapContext = new BootstrapContext (securityToken, securityTokenHandler);
139 Assert.IsNotNull (bootstrapContext.SecurityToken, "#1");
140 Assert.AreEqual (user, securityToken.UserName, "#2");
141 Assert.AreEqual (password, securityToken.Password, "#3");
142 Assert.AreEqual (securityTokenHandler, bootstrapContext.SecurityTokenHandler, "#4");
144 Assert.IsNull (bootstrapContext.Token, "#5");
145 Assert.IsNull (bootstrapContext.TokenBytes, "#6");
149 [ExpectedException (typeof (ArgumentNullException))]
150 public void Ctor_SecurityToken_NullToken_Throws ()
152 BootstrapContext bootstrapContext = new BootstrapContext (null, new SimpleSecurityTokenHandler ());
153 Assert.Fail ("Should have thrown");
157 [ExpectedException (typeof (ArgumentNullException))]
158 public void Ctor_SecurityToken_NullHandler_Throws ()
160 BootstrapContext bootstrapContext = new BootstrapContext (new UserNameSecurityToken ("user", "password"), null);
161 Assert.Fail ("Should have thrown");
165 public void Serialize_SecurityTokenAndHandler_Works ()
167 var securityToken = new UserNameSecurityToken (user, password, "uuid-927c0b98-ba18-49d2-a653-306d60f85751-3");
168 var securityTokenHandler = new SimpleSecurityTokenHandler ();
169 BootstrapContext bootstrapContext = new BootstrapContext (securityToken, securityTokenHandler);
171 BinaryFormatter binaryFormatter = new BinaryFormatter ();
172 using (var s = new MemoryStream ()) {
173 binaryFormatter.Serialize (s, bootstrapContext);
175 BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext;
176 Assert.IsNotNull (bootstrapContext2, "#1");
177 // Deserialize does not restore the SecurityToken, but restores into the Token.
178 Assert.IsNotNull (bootstrapContext2.Token, "#3");
179 // We replace ' /' by '/' to accomodate the xml writer differences between mono and .net
180 Assert.AreEqual (SerializedBootstrapContextSecurityTokenString.Replace (" /", "/"), bootstrapContext2.Token.Replace (" /", "/"), "#2");
181 Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3");
182 Assert.IsNull (bootstrapContext2.SecurityToken, "#4");
183 Assert.IsNull (bootstrapContext2.SecurityTokenHandler, "#5");
188 public void Deserialize_SecurityTokenAndHandler_Works ()
190 BinaryFormatter binaryFormatter = new BinaryFormatter ();
191 using (var s = new MemoryStream (SerializedBootstrapContextSecurityToken)) {
192 BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext;
193 Assert.IsNotNull (bootstrapContext, "#1");
194 Assert.AreEqual (SerializedBootstrapContextSecurityTokenString, bootstrapContext.Token, "#2");
195 Assert.IsNull (bootstrapContext.SecurityToken, "#3");
196 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#4");
197 Assert.IsNull (bootstrapContext.TokenBytes, "#5");
201 private static void DumpAsText (byte [] data)
203 Console.WriteLine ("{0}", Encoding.ASCII.GetString (data));
206 private static void Dump (byte [] data)
208 var sb = new StringBuilder ();
209 sb.Append ("new byte[] { ");
211 foreach (byte b in data) {
216 sb.AppendFormat ("0x{0:X2}", b);
219 Console.WriteLine (sb.ToString ());
222 private class SimpleSecurityTokenHandler : SecurityTokenHandler {
223 public override string [] GetTokenTypeIdentifiers ()
225 throw new NotImplementedException ();
228 public override Type TokenType {
229 get { return typeof (UserNameSecurityToken); }
232 public override bool CanWriteToken {
236 public override void WriteToken (XmlWriter writer, SecurityToken token)
238 UserNameSecurityToken unst = token as UserNameSecurityToken;
240 throw new ArgumentException ("Token must be of type UserNameSecurityToken", "token");
241 writer.WriteStartElement ("UserNameSecurityToken");
242 writer.WriteAttributeString ("Id", unst.Id);
243 writer.WriteAttributeString ("Username", unst.UserName);
244 writer.WriteAttributeString ("Password", unst.Password);
245 writer.WriteEndElement ();