public override SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor)
        {
            if (tokenDescriptor == null)
            {
                throw new ArgumentNullException("tokenDescriptor");
            }

            var properties = new NameValueCollection
            {
                { SimpleWebTokenConstants.Id, Guid.NewGuid().ToString() },
                { SimpleWebTokenConstants.Issuer, tokenDescriptor.TokenIssuerName },
                { SimpleWebTokenConstants.Audience, tokenDescriptor.AppliesToAddress },
                { SimpleWebTokenConstants.ExpiresOn, SecondsFromSwtBaseTime(tokenDescriptor.Lifetime.Expires) },
                { SimpleWebTokenConstants.ValidFrom, SecondsFromSwtBaseTime(tokenDescriptor.Lifetime.Created) }
            };

            foreach (var claim in tokenDescriptor.Subject.Claims)
            {
                properties.Add(claim.Type, claim.Value);
            }

            var token = new SimpleWebToken(properties, tokenDescriptor.SigningCredentials.SigningKey);

            return(token);
        }
        /// <summary>
        /// Parses the string token and generates a <see cref="SecurityToken"/>.
        /// </summary>
        /// <param name="serializedToken">The serialized form of the token received.</param>
        /// <returns>The parsed form of the token.</returns>
        protected SecurityToken ReadSecurityTokenFromString(string serializedToken)
        {
            if (String.IsNullOrEmpty(serializedToken))
            {
                throw new ArgumentException("The parameter 'serializedToken' cannot be null or empty string.");
            }

            // Create a collection of SWT name value pairs
            var properties = ParseToken(serializedToken);
            var swt        = new SimpleWebToken(properties, serializedToken, null);

            return(swt);
        }
        /// <summary>
        /// Validates the signature on the incoming token.
        /// </summary>
        /// <param name="simpleWebToken">The incoming <see cref="SimpleWebToken"/>.</param>
        protected virtual void ValidateSignature(SimpleWebToken simpleWebToken)
        {
            if (simpleWebToken == null)
            {
                throw new ArgumentNullException("simpleWebToken");
            }

            if (String.IsNullOrEmpty(simpleWebToken.SerializedToken) || String.IsNullOrEmpty(simpleWebToken.Signature))
            {
                throw new SecurityTokenValidationException("The token does not have a signature to verify");
            }

            var    serializedToken = simpleWebToken.SerializedToken;
            string unsignedToken   = null;

            // Find the last parameter. The signature must be last per SWT specification.
            var lastSeparator = serializedToken.LastIndexOf(ParameterSeparator);

            // Check whether the last parameter is an hmac.
            if (lastSeparator > 0)
            {
                var lastParamStart = ParameterSeparator + SimpleWebTokenConstants.Signature + "=";
                var lastParam      = serializedToken.Substring(lastSeparator);

                // Strip the trailing hmac to obtain the original unsigned string for later hmac verification.
                if (lastParam.StartsWith(lastParamStart, StringComparison.Ordinal))
                {
                    unsignedToken = serializedToken.Substring(0, lastSeparator);
                }
            }

            var clause = new SimpleWebTokenKeyIdentifierClause(simpleWebToken.Audience);
            InMemorySymmetricSecurityKey securityKey = null;

            try
            {
                securityKey = (InMemorySymmetricSecurityKey)this.Configuration.IssuerTokenResolver.ResolveSecurityKey(clause);
            }
            catch (InvalidOperationException)
            {
                throw new SecurityTokenValidationException("A Symmetric key was not found for the given key identifier clause.");
            }

            var generatedSignature = GenerateSignature(unsignedToken, securityKey.GetSymmetricKey());

            if (string.CompareOrdinal(HttpUtility.UrlDecode(generatedSignature), HttpUtility.UrlDecode(simpleWebToken.Signature)) != 0)
            {
                throw new SecurityTokenValidationException("The signature on the incoming token is invalid.");
            }
        }
        /// <summary>Creates <see cref="Claim"/>'s from the incoming token.
        /// </summary>
        /// <param name="simpleWebToken">The incoming <see cref="SimpleWebToken"/>.</param>
        /// <returns>A <see cref="ClaimsIdentity"/> created from the token.</returns>
        protected virtual ClaimsIdentity CreateClaims(SimpleWebToken simpleWebToken)
        {
            if (simpleWebToken == null)
            {
                throw new ArgumentNullException("simpleWebToken");
            }

            var tokenProperties = simpleWebToken.GetAllProperties();

            if (tokenProperties == null)
            {
                throw new SecurityTokenValidationException("No claims can be created from this Simple Web Token.");
            }

            if (Configuration.IssuerNameRegistry == null)
            {
                throw new InvalidOperationException("The Configuration.IssuerNameRegistry property of this SecurityTokenHandler is set to null. Tokens cannot be validated in this state.");
            }

            var normalizedIssuer = Configuration.IssuerNameRegistry.GetIssuerName(simpleWebToken);

            var identity = new ClaimsIdentity(AuthenticationTypes.Federation);

            foreach (string key in tokenProperties.Keys)
            {
                if (!IsReservedKeyName(key) && !string.IsNullOrEmpty(tokenProperties[key]))
                {
                    identity.AddClaim(new Claim(key, tokenProperties[key], ClaimValueTypes.String, normalizedIssuer));
                    if (key == AcsNameClaimType)
                    {
                        // add a default name claim from the Name identifier claim.
                        identity.AddClaim(new Claim(DefaultNameClaimType, tokenProperties[key], ClaimValueTypes.String, normalizedIssuer));
                    }
                }
            }

            return(identity);
        }