Esempio n. 1
0
        static GenericXmlSecurityToken WrapJwt(string jwt)
        {
            var subject = new ClaimsIdentity("saml");
            subject.AddClaim(new Claim("jwt", jwt));

            var descriptor = new SecurityTokenDescriptor
            {
                TokenType = TokenTypes.Saml2TokenProfile11,
                TokenIssuerName = "urn:wrappedjwt",
                Subject = subject
            };

            var handler = new Saml2SecurityTokenHandler();
            var token = handler.CreateToken(descriptor);

            var xmlToken = new GenericXmlSecurityToken(
                XElement.Parse(token.ToTokenXmlString()).ToXmlElement(),
                null,
                DateTime.Now,
                DateTime.Now.AddHours(1),
                null,
                null,
                null);

            return xmlToken;
        }
 public Saml2AssertionFactory(ISaml2AssertionValidationOptions options)
 {
     if (options.Audience == null)
         throw new ArgumentNullException("Audience");
     if (options.Recipient == null)
         throw new ArgumentNullException("Recipient");
     if (options.Certificate == null)
         throw new ArgumentNullException("certificate");
     configuration = GetSecurityTokenHandlerConfiguration(options);
     tokenHandler = new Saml2BearerGrantSecurityTokenHandler(options.Recipient);
     tokenHandler.Configuration = configuration;
 }
        public string ToXml(Saml2Assertion assertion)
        {
            var tokenHandlers = new Saml2SecurityTokenHandler();
            var stringBuilder = new StringBuilder();
            using (var xmlWriter = new XmlTextWriter(new StringWriter(stringBuilder)))
            {
                var token = new Saml2SecurityToken(assertion);
                tokenHandlers.WriteToken(xmlWriter, token);

                return stringBuilder.ToString();
            }
        }
        /// <summary>
        /// Authenticates the specified message.
        /// </summary>
        /// <returns>
        /// Returns <see cref="T:System.Collections.ObjectModel.ReadOnlyCollection`1"/>.
        /// </returns>
        /// <param name="authPolicy">The authorization policy.</param><param name="listenUri">The URI at which the message was received.</param><param name="message">The message to be authenticated.</param>
        public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message)
        {
            if (WebOperationContext.Current != null && WebOperationContext.Current.IncomingRequest.Headers["fedAuth"] != null)
            {

                var tokenString = WebOperationContext.Current.IncomingRequest.Headers["fedAuth"];
                var handler = new Saml2SecurityTokenHandler();
                var token = handler.ReadToken(tokenString);
                var identities = handler.ValidateToken(token);
                var principal = new ClaimsPrincipal(identities);
                Thread.CurrentPrincipal = principal;
            }
            return base.Authenticate(authPolicy, listenUri, ref message);
        }
        public void CrossToken_ValidateToken()
        {
            JwtSecurityTokenHandler jwtHandler     = new JwtSecurityTokenHandler();
            IMSaml2TokenHandler     imSaml2Handler = new IMSaml2TokenHandler();
            IMSamlTokenHandler      imSamlHandler  = new IMSamlTokenHandler();
            SMSaml2TokenHandler     smSaml2Handler = new SMSaml2TokenHandler();
            SMSamlTokenHandler      smSamlHandler  = new SMSamlTokenHandler();

            JwtSecurityTokenHandler.InboundClaimFilter.Add("aud");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("exp");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("iat");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("iss");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("nbf");

            string jwtToken = IdentityUtilities.CreateJwtToken(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, jwtHandler);

            // saml tokens created using Microsoft.IdentityModel.Extensions
            string imSaml2Token = IdentityUtilities.CreateSaml2Token(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, imSaml2Handler);
            string imSamlToken  = IdentityUtilities.CreateSamlToken(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, imSamlHandler);

            // saml tokens created using System.IdentityModel.Tokens
            string smSaml2Token = IdentityUtilities.CreateSaml2Token(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, smSaml2Handler);
            string smSamlToken  = IdentityUtilities.CreateSamlToken(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, smSamlHandler);

            ClaimsPrincipal jwtPrincipal     = ValidateToken(jwtToken, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, jwtHandler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal imSaml2Principal = ValidateToken(imSaml2Token, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSaml2Handler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal imSamlPrincipal  = ValidateToken(imSamlToken, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSamlHandler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal smSaml2Principal = ValidateToken(smSaml2Token, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSaml2Handler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal smSamlPrincipal  = ValidateToken(smSamlToken, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSamlHandler, ExpectedException.NoExceptionExpected);

            Assert.IsTrue(IdentityComparer.AreEqual <ClaimsPrincipal>(imSamlPrincipal, imSaml2Principal, new CompareContext {
                IgnoreSubject = true
            }));
            Assert.IsTrue(IdentityComparer.AreEqual <ClaimsPrincipal>(smSamlPrincipal, imSaml2Principal, new CompareContext {
                IgnoreSubject = true
            }));
            Assert.IsTrue(IdentityComparer.AreEqual <ClaimsPrincipal>(smSaml2Principal, imSaml2Principal, new CompareContext {
                IgnoreSubject = true
            }));

            // false = ignore type of objects, we expect all objects in the principal to be of same type (no derived types)
            // true = ignore subject, claims have a backpointer to their ClaimsIdentity.  Most of the time this will be different as we are comparing two different ClaimsIdentities.
            // true = ignore properties of claims, any mapped claims short to long for JWT's will have a property that represents the short type.
            Assert.IsTrue(IdentityComparer.AreEqual <ClaimsPrincipal>(jwtPrincipal, imSaml2Principal, new CompareContext {
                IgnoreType = false, IgnoreSubject = true, IgnoreProperties = true
            }));

            JwtSecurityTokenHandler.InboundClaimFilter.Clear();
        }
        /// <summary>
        /// Initializes an instance of <see cref="WrappedSaml2SecurityTokenAuthenticator"/>
        /// </summary>
        /// <param name="saml2SecurityTokenHandler">The Saml2SecurityTokenHandler to wrap.</param>
        /// <param name="exceptionMapper">Converts token validation exceptions to SOAP faults.</param>
        public WrappedSaml2SecurityTokenAuthenticator( 
            Saml2SecurityTokenHandler saml2SecurityTokenHandler, 
            ExceptionMapper exceptionMapper )
        {
            if ( saml2SecurityTokenHandler == null )
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "wrappedSaml2SecurityTokenHandler" );
            }

            if ( exceptionMapper == null )
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "exceptionMapper" );
            }

            _wrappedSaml2SecurityTokenHandler = saml2SecurityTokenHandler;
            _exceptionMapper = exceptionMapper;
        }
        public static string CreateSaml2Token(string name)
        {
            var id = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, name) }, "SAML");

            var descriptor = new SecurityTokenDescriptor
            {
                Subject = id,
                AppliesToAddress = "https://test",
                TokenIssuerName = "http://issuer",
                SigningCredentials = GetSamlSigningCredential(),
            };

            var handler = new Saml2SecurityTokenHandler();
            handler.Configuration = new SecurityTokenHandlerConfiguration();

            var token = handler.CreateToken(descriptor);
            return token.ToTokenXmlString();
        }
Esempio n. 8
0
        private static SecurityToken GenerateHardcodedToken()
        {
            var securityTokenDescriptor = new SecurityTokenDescriptor();
            securityTokenDescriptor.Subject = ClaimsPrincipal.Current.Identity as ClaimsIdentity;
            securityTokenDescriptor.Lifetime = new Lifetime(DateTime.Now, DateTime.Now.AddDays(2));
            securityTokenDescriptor.TokenIssuerName = "http://identityserver.v2.thinktecture.com/trust/changethis";
            securityTokenDescriptor.AppliesToAddress = "https://windows7:444/identity/wstrust/bearer";
            securityTokenDescriptor.SigningCredentials = GenerateSigningCredentials();

            Saml2SecurityTokenHandler saml2SecurityTokenHandler = new Saml2SecurityTokenHandler();
            var saml2SecurityToken = saml2SecurityTokenHandler.CreateToken(securityTokenDescriptor) as Saml2SecurityToken;

            var authenticationMethod = "urn:oasis:names:tc:SAML:2.0:ac:classes:Password";
            var authenticationContext = new Saml2AuthenticationContext(new Uri(authenticationMethod));
            saml2SecurityToken.Assertion.Statements.Add(new Saml2AuthenticationStatement(authenticationContext));

            return saml2SecurityToken;
        }
        public void CrossToken_ValidateToken()
        {
            JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();
            IMSaml2TokenHandler imSaml2Handler = new IMSaml2TokenHandler();
            IMSamlTokenHandler imSamlHandler = new IMSamlTokenHandler();
            SMSaml2TokenHandler smSaml2Handler = new SMSaml2TokenHandler();
            SMSamlTokenHandler smSamlHandler = new SMSamlTokenHandler();

            JwtSecurityTokenHandler.InboundClaimFilter.Add("aud");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("exp");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("iat");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("iss");
            JwtSecurityTokenHandler.InboundClaimFilter.Add("nbf");

            string jwtToken = IdentityUtilities.CreateJwtToken(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, jwtHandler);

            // saml tokens created using Microsoft.IdentityModel.Extensions
            string imSaml2Token = IdentityUtilities.CreateSaml2Token(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, imSaml2Handler);
            string imSamlToken = IdentityUtilities.CreateSamlToken(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, imSamlHandler);

            // saml tokens created using System.IdentityModel.Tokens
            string smSaml2Token = IdentityUtilities.CreateSaml2Token(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, smSaml2Handler);
            string smSamlToken = IdentityUtilities.CreateSamlToken(IdentityUtilities.DefaultAsymmetricSecurityTokenDescriptor, smSamlHandler);

            ClaimsPrincipal jwtPrincipal = ValidateToken(jwtToken, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, jwtHandler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal imSaml2Principal = ValidateToken(imSaml2Token, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSaml2Handler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal imSamlPrincipal = ValidateToken(imSamlToken, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSamlHandler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal smSaml2Principal = ValidateToken(smSaml2Token, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSaml2Handler, ExpectedException.NoExceptionExpected);
            ClaimsPrincipal smSamlPrincipal = ValidateToken(smSamlToken, IdentityUtilities.DefaultAsymmetricTokenValidationParameters, imSamlHandler, ExpectedException.NoExceptionExpected);

            Assert.IsTrue(IdentityComparer.AreEqual<ClaimsPrincipal>(imSamlPrincipal,  imSaml2Principal, new CompareContext { IgnoreSubject = true }));
            Assert.IsTrue(IdentityComparer.AreEqual<ClaimsPrincipal>(smSamlPrincipal,  imSaml2Principal, new CompareContext { IgnoreSubject = true }));
            Assert.IsTrue(IdentityComparer.AreEqual<ClaimsPrincipal>(smSaml2Principal, imSaml2Principal, new CompareContext { IgnoreSubject = true }));

            // false = ignore type of objects, we expect all objects in the principal to be of same type (no derived types)
            // true = ignore subject, claims have a backpointer to their ClaimsIdentity.  Most of the time this will be different as we are comparing two different ClaimsIdentities.
            // true = ignore properties of claims, any mapped claims short to long for JWT's will have a property that represents the short type.
            Assert.IsTrue(IdentityComparer.AreEqual<ClaimsPrincipal>(jwtPrincipal, imSaml2Principal, new CompareContext{IgnoreType = false, IgnoreSubject = true, IgnoreProperties=true}));

            JwtSecurityTokenHandler.InboundClaimFilter.Clear();
        }
        static void Main(string[] args)
        {
            Console.SetWindowSize(Console.LargestWindowWidth / 2, Console.LargestWindowHeight / 2);

            Console.WriteLine("Requesting security token from \"{0}\" for resource \"{1}\"...", PF_IP_STS_Endpoint, IPSTS_appliesTo);
            Console.WriteLine();

            try
            {
                // To Issue the initial token (ie the Web Services Client (WSC) doing its thing, we are going to auth with a username and a password

                // Issue the initial SAML token
                RequestSecurityTokenResponse RSTR_Issue;
                SecurityToken token = IssueTokenWithUserNamePassword(subject_username, subject_password, PF_IP_STS_Endpoint, IPSTS_appliesTo, out RSTR_Issue, KeyTypes.Bearer);

                // When using Asymmetric Key (HoK) - we need to supply a UseKey
                // When using Symmetric Key (HoK) - SP Encryption cert is not defined - unless encryption key available to use as subj confirmation

                if (token != null)
                {
                    //show the token
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("{0}", token);
                    Console.WriteLine();
                    Console.WriteLine("{0}", RSTR_Issue.RequestedSecurityToken.SecurityTokenXml.InnerXml);
                    Console.WriteLine();

                    // At this point we received a token from our STS.  We can now use it to authenticate to our web service using it as an IssuedToken.
                    // ... here is where the WSP kicks in...
                    //
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Console.WriteLine();
                    Console.WriteLine("Do you want to validate the security token? [Y]");

                    if (Console.ReadKey(true).Key == ConsoleKey.Y)
                    {
                        Console.WriteLine("Validating security token with \"{0}\"...", PF_RP_STS_Endpoint);
                        Console.WriteLine();

                        // We are acting as the WSP now.  We want to Validate the SAML token against PingFederate's STS
                        RequestSecurityTokenResponse RSTR_Validate = ValidateSecurityToken(token, PF_RP_STS_Endpoint);

                        // This will return:
                        // http://docs.oasis-open.org/ws-sx/ws-trust/200512/status/valid or
                        // http://docs.oasis-open.org/ws-sx/ws-trust/200512/status/invalid
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("{0}", RSTR_Validate.Status.Code);
                        Console.WriteLine();

                        // So we have a valid token supplied by the web services client.... we can grab the claims from there and do as we wish... or.. we can issue a local token
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine();
                        Console.WriteLine("Do you want to issue a local security token? [Y]");

                        if (Console.ReadKey(true).Key == ConsoleKey.Y)
                        {
                            Console.WriteLine("Requesting \"{0}\" security token from \"{1}\"...", tokenType, PF_RP_STS_Endpoint);
                            Console.WriteLine();

                            // We need to make a call to our RP-STS (SP side of PF) to issue a local token (according to our Token Generator)
                            //SecurityToken localToken = IssueLocalSecurityToken(token, RPSTS_issuerUri, RPSTS_appliesTo, tokenType, keyType);

                            // I'm going to receive it as a GenericXmlSecurityToken so we can parse it easier later on...
                            RequestSecurityTokenResponse RSTR_LocalToken;
                            GenericXmlSecurityToken xmlToken = (GenericXmlSecurityToken)IssueLocalSecurityToken(token, PF_RP_STS_Endpoint, tokenType, out RSTR_LocalToken);

                            if (xmlToken != null)
                            {
                                //show the token
                                Console.ForegroundColor = ConsoleColor.Green;
                                Console.WriteLine("{0}", xmlToken);

                                // parse token to grab the attributes:
                                if (tokenType == "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0")
                                {

                                    // Configure the IssuerNameRegistry
                                    ConfigurationBasedIssuerNameRegistry myIssuerNameRegistry = new ConfigurationBasedIssuerNameRegistry();
                                    myIssuerNameRegistry.AddTrustedIssuer(PF_Signing_Cert_Thumbprint, "RP-STS"); // this is the dsig cert (of my RP-STS) SHA1 thumbprint | name
                                    //inr.AddTrustedIssuer("97463668CD4482AFAC7F341A1C3ABB1010757800", "localhost"); // this is the encryption cert (of my RP-STS - bearer token isn't encrypted tho)

                                    // Define the "verification configuration"
                                    SecurityTokenHandlerConfiguration securityTokenHanderConfig = new SecurityTokenHandlerConfiguration();
                                    securityTokenHanderConfig.AudienceRestriction.AllowedAudienceUris.Add(new Uri("https://www.app.com")); // the Audience defined in the Token Generator
                                    Saml2SecurityTokenHandler saml2TokenHandler = new Saml2SecurityTokenHandler();
                                    securityTokenHanderConfig.IssuerNameRegistry = myIssuerNameRegistry;
                                    saml2TokenHandler.Configuration = securityTokenHanderConfig;

                                    // Parse the token and return a Claims Identity
                                    SecurityToken saml2Token = saml2TokenHandler.ReadToken(new XmlTextReader(new StringReader(xmlToken.TokenXml.OuterXml)));
                                    ClaimsIdentity identity = saml2TokenHandler.ValidateToken(saml2Token).First();

                                    // Spit out the Claims
                                    Console.WriteLine("Attributes in the Assertion.....");
                                    Console.WriteLine("{0}", identity.Name);
                                    foreach (Claim theClaim in identity.Claims)
                                    {
                                        Console.WriteLine("{0} : {1}", theClaim.Type, theClaim.Value);
                                    }
                                }
                                else if (tokenType == "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0")
                                {

                                }

                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ConsoleColor PreviousColor = Console.ForegroundColor;

                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);

                if (ex.InnerException != null)
                {
                    Console.WriteLine();
                    Console.WriteLine(ex.InnerException.Message);
                }

                Console.ForegroundColor = PreviousColor;
            }

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Press <enter> to close.");
            Console.Read();
        }
Esempio n. 11
0
        public void Saml2Response_GetClaims_CorrectEncryptedSingleAssertion_UsingWIF()
        {
            var response =
            @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol""
            xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion""
            ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"">
                <saml2:Issuer>https://idp.example.com</saml2:Issuer>
                <saml2p:Status>
                    <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" />
                </saml2p:Status>
                {0}
            </saml2p:Response>";

            var assertion = new Saml2Assertion(new Saml2NameIdentifier("https://idp.example.com"));
            assertion.Subject = new Saml2Subject(new Saml2NameIdentifier("WIFUser"));
            assertion.Subject.SubjectConfirmations.Add(new Saml2SubjectConfirmation(new Uri("urn:oasis:names:tc:SAML:2.0:cm:bearer")));
            assertion.Conditions = new Saml2Conditions { NotOnOrAfter = new DateTime(2100, 1, 1) };

            var token = new Saml2SecurityToken(assertion);
            var handler = new Saml2SecurityTokenHandler();

            assertion.SigningCredentials = new X509SigningCredentials(SignedXmlHelper.TestCert,
                signatureAlgorithm: SecurityAlgorithms.RsaSha1Signature,
                digestAlgorithm: SecurityAlgorithms.Sha1Digest);

            assertion.EncryptingCredentials = new EncryptedKeyEncryptingCredentials(
                SignedXmlHelper.TestCert2,
                keyWrappingAlgorithm: SecurityAlgorithms.RsaOaepKeyWrap,
                keySizeInBits: 256,
                encryptionAlgorithm: SecurityAlgorithms.Aes192Encryption);

            string assertionXml = String.Empty;
            using (var sw = new StringWriter())
            {
                using (var xw = XmlWriter.Create(sw, new XmlWriterSettings { OmitXmlDeclaration = true }))
                {
                    handler.WriteToken(xw, token);
                }
                assertionXml = sw.ToString();
            }
            var responseWithAssertion = string.Format(response, assertionXml);

            var claims = Saml2Response.Read(responseWithAssertion).GetClaims(Options.FromConfiguration);
            claims.Count().Should().Be(1);
            claims.First().FindFirst(ClaimTypes.NameIdentifier).Value.Should().Be("WIFUser");
        }
 public WrappedSerializer(Saml2SecurityTokenHandler parent, Saml2Assertion assertion)
 {
     this.assertion = assertion;
     this.parent = parent;
 }
 private void CreateSaml2Tokens( SecurityTokenDescriptor tokenDescriptor )
 {
     Saml2SecurityTokenHandler samlTokenHandler = new Saml2SecurityTokenHandler();
     Saml2SecurityToken  token = samlTokenHandler.CreateToken( tokenDescriptor ) as Saml2SecurityToken;
     MemoryStream ms = new MemoryStream();
     XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter( ms );
     samlTokenHandler.WriteToken( writer, token );
 }
        private void RunValidationTests( SecurityTokenDescriptor tokenDescriptor, SecurityToken securityToken, SecurityKey key, int iterations, bool display = true )
        {
            // Create jwts using wif
            // Create Saml2 tokens
            // Create Saml tokens

            DateTime started;
            string validating = "Validating, signed: '{0}', '{1}' Tokens. Time: '{2}'";

            SetReturnSecurityTokenResolver str = new Test.SetReturnSecurityTokenResolver( securityToken, key );
            
            SecurityTokenHandlerConfiguration tokenHandlerConfiguration = new SecurityTokenHandlerConfiguration()
            {
                IssuerTokenResolver = str,
                SaveBootstrapContext = true,
                CertificateValidator = AlwaysSucceedCertificateValidator.New,
                AudienceRestriction = new AudienceRestriction( AudienceUriMode.Never ),
                IssuerNameRegistry = new SetNameIssuerNameRegistry( Issuers.GotJwt ),
            };

            Saml2SecurityTokenHandler samlTokenHandler = new Saml2SecurityTokenHandler();
            Saml2SecurityToken token = samlTokenHandler.CreateToken( tokenDescriptor ) as Saml2SecurityToken;
            StringBuilder sb = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(sb);
            samlTokenHandler.WriteToken( writer, token );                                    
            writer.Flush();
            writer.Close();
            string tokenXml = sb.ToString();

            samlTokenHandler.Configuration = tokenHandlerConfiguration;
            started = DateTime.UtcNow;
            for ( int i = 0; i < iterations; i++ )
            {
                StringReader sr = new StringReader( tokenXml );
                XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader( XmlReader.Create( sr ) );
                reader.MoveToContent();
                SecurityToken saml2Token = samlTokenHandler.ReadToken( reader );
                samlTokenHandler.ValidateToken( saml2Token );
            }
            if ( display )
            {
                Console.WriteLine( string.Format( validating, "Saml2SecurityTokenHandler", iterations, DateTime.UtcNow - started ) );
            }

            JwtSecurityTokenHandler jwtTokenHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken jwt = jwtTokenHandler.CreateToken( tokenDescriptor ) as JwtSecurityToken;
            jwtTokenHandler.Configuration = tokenHandlerConfiguration;
            started = DateTime.UtcNow;
            for ( int i = 0; i < iterations; i++ )
            {
                jwtTokenHandler.ValidateToken( jwt.RawData );
            }

            if ( display )
            {
                Console.WriteLine( string.Format( validating, "JwtSecurityTokenHandle - ValidateToken( jwt.RawData )", iterations, DateTime.UtcNow - started ) );
            }

            jwt = jwtTokenHandler.CreateToken( tokenDescriptor ) as JwtSecurityToken;
            sb = new StringBuilder();
            writer = XmlWriter.Create(sb);
            jwtTokenHandler.WriteToken( writer, jwt );                                    
            writer.Flush();
            writer.Close();
            tokenXml = sb.ToString();

            started = DateTime.UtcNow;
            for ( int i = 0; i<iterations; i++ )
            {
                StringReader sr = new StringReader( tokenXml );
                XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader( XmlReader.Create( sr ) );
                reader.MoveToContent();
                SecurityToken jwtToken = jwtTokenHandler.ReadToken( reader );
                jwtTokenHandler.ValidateToken( jwtToken );
            }

            if ( display )
            {
                Console.WriteLine( string.Format( validating, "JwtSecurityTokenHandle - ReadToken( reader ), ValidateToken( jwtToken )", iterations, DateTime.UtcNow - started ) );
            }

            started = DateTime.UtcNow;
            for ( int i = 0; i < iterations; i++ )
            {
                StringReader sr = new StringReader( tokenXml );
                XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader( XmlReader.Create( sr ) );
                reader.MoveToContent();
                JwtSecurityToken jwtToken = jwtTokenHandler.ReadToken( reader ) as JwtSecurityToken;
                jwtTokenHandler.ValidateToken( jwtToken.RawData );
            }

            if ( display )
            {
                Console.WriteLine( string.Format( validating, "JwtSecurityTokenHandle - ReadToken( reader ), ValidateToken( jwtToken.RawData )", iterations, DateTime.UtcNow - started ) );
            }
        }