/// <summary>
        /// This methos validates the Simple Web Token.
        /// </summary>
        /// <param name="token">A simple web token.</param>
        /// <param name="realm">The realm.</param>
        /// <returns>
        /// A Claims Collection which contains all the claims from the token.
        /// </returns>
        public ClaimsIdentityCollection ValidateToken(SecurityToken token, string realm)
        {
            SimpleWebToken realToken = token as SimpleWebToken;

            if (realToken == null)
            {
                throw new InvalidTokenReceivedException("The received token is of incorrect token type. Expected SimpleWebToken");
            }

            if (StringComparer.OrdinalIgnoreCase.Compare(realToken.AudienceUri.ToString(), realm) != 0)
            {
                throw new InvalidTokenReceivedException("The Audience Uri of the incoming token is not expected. Expected AudienceUri is " + realm);
            }

            if (StringComparer.OrdinalIgnoreCase.Compare(realToken.Issuer, _issuer) != 0)
            {
                throw new InvalidTokenReceivedException("The Issuer of the token is not trusted. Trusted issuer is " + _issuer);
            }

            if (!realToken.SignVerify(Convert.FromBase64String(_symmetricSignatureKey)))
            {
                throw new InvalidTokenReceivedException("Signature verification of the incoming token failed.");
            }

            if (DateTime.Compare(realToken.ValidTo, DateTime.UtcNow) <= 0)
            {
                throw new ExpiredTokenReceivedException("The incoming token has expired. Get a new access token from the Authorization Server.");
            }

            ClaimsIdentityCollection identities = new ClaimsIdentityCollection();
            ClaimsIdentity           identity   = new ClaimsIdentity();

            foreach (var claim in realToken.Claims)
            {
                identity.Claims.Add(claim);
            }

            identities.Add(identity);

            return(identities);
        }
        /// <summary>
        /// Reads a serialized token and converts it into a <see cref="SecurityToken"/>.
        /// </summary>
        /// <param name="rawToken">The token in serialized form.</param>
        /// <returns>The parsed form of the token.</returns>
        public SecurityToken ReadToken(string rawToken)
        {
            if (!rawToken.Contains("&"))
            {
                rawToken = Encoding.UTF8.GetString(Convert.FromBase64String(rawToken));
            }

            char   parameterSeparator = '&';
            Uri    audienceUri        = null;
            string issuer             = null;
            string signature          = null;
            string unsignedString     = null;
            string expires            = null;

            if (string.IsNullOrEmpty(rawToken))
            {
                throw new ArgumentNullException("rawToken");
            }

            //
            // Find the last parameter. The signature must be last per SWT specification.
            //
            int lastSeparator = rawToken.LastIndexOf(parameterSeparator);

            // Check whether the last parameter is an hmac.
            //
            if (lastSeparator > 0)
            {
                string lastParamStart = parameterSeparator + Digest256Label + "=";
                string lastParam      = rawToken.Substring(lastSeparator);

                // Strip the trailing hmac to obtain the original unsigned string for later hmac verification.
                // e.g. name1=value1&name2=value2&HMACSHA256=XXX123 -> name1=value1&name2=value2
                //
                if (lastParam.StartsWith(lastParamStart, StringComparison.Ordinal))
                {
                    unsignedString = rawToken.Substring(0, lastSeparator);
                }
            }
            else
            {
                throw new InvalidTokenReceivedException("The Simple Web Token must have a signature at the end. The incoming token did not have a signature at the end of the token.");
            }

            // Signature is a mandatory parameter, and it must be the last one.
            // If there's no trailing hmac, Return error.
            //
            if (unsignedString == null)
            {
                throw new InvalidTokenReceivedException("The Simple Web Token must have a signature at the end. The incoming token did not have a signature at the end of the token.");
            }

            // Create a collection of SWT claims
            //
            NameValueCollection rawClaims = ParseToken(rawToken);

            audienceUri = new Uri(rawClaims[AudienceLabel]);
            if (audienceUri != null)
            {
                rawClaims.Remove(AudienceLabel);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have an AudienceUri.");
            }

            expires = rawClaims[ExpiresOnLabel];
            if (expires != null)
            {
                rawClaims.Remove(ExpiresOnLabel);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have an expiry time.");
            }

            issuer = rawClaims[IssuerLabel];
            if (issuer != null)
            {
                rawClaims.Remove(IssuerLabel);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have an Issuer");
            }

            signature = rawClaims[Digest256Label];
            if (signature != null)
            {
                rawClaims.Remove(Digest256Label);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have a signature");
            }

            List <Claim> claims = DecodeClaims(issuer, rawClaims);

            SimpleWebToken swt = new SimpleWebToken(audienceUri, issuer, DecodeExpiry(expires), claims, signature, unsignedString);

            return(swt);
        }
        /// <summary>
        /// Reads a serialized token and converts it into a <see cref="SecurityToken"/>.
        /// </summary>
        /// <param name="rawToken">The token in serialized form.</param>
        /// <returns>The parsed form of the token.</returns>
        public SecurityToken ReadToken(string rawToken)
        {
            if (!rawToken.Contains("&"))
            {
                rawToken = Encoding.UTF8.GetString(Convert.FromBase64String(rawToken));
            }

            char parameterSeparator = '&';
            Uri audienceUri = null;
            string issuer = null;
            string signature = null;
            string unsignedString = null;
            string expires = null;

            if (string.IsNullOrEmpty(rawToken))
            {
                throw new ArgumentNullException("rawToken");
            }

            //
            // Find the last parameter. The signature must be last per SWT specification.
            //
            int lastSeparator = rawToken.LastIndexOf(parameterSeparator);

            // Check whether the last parameter is an hmac.
            //
            if (lastSeparator > 0)
            {
                string lastParamStart = parameterSeparator + Digest256Label + "=";
                string lastParam = rawToken.Substring(lastSeparator);

                // Strip the trailing hmac to obtain the original unsigned string for later hmac verification.
                // e.g. name1=value1&name2=value2&HMACSHA256=XXX123 -> name1=value1&name2=value2
                //
                if (lastParam.StartsWith(lastParamStart, StringComparison.Ordinal))
                {
                    unsignedString = rawToken.Substring(0, lastSeparator);
                }
            }
            else
            {
                throw new InvalidTokenReceivedException("The Simple Web Token must have a signature at the end. The incoming token did not have a signature at the end of the token.");
            }

            // Signature is a mandatory parameter, and it must be the last one.
            // If there's no trailing hmac, Return error.
            //
            if (unsignedString == null)
            {
                throw new InvalidTokenReceivedException("The Simple Web Token must have a signature at the end. The incoming token did not have a signature at the end of the token.");
            }

            // Create a collection of SWT claims
            //
            NameValueCollection rawClaims = ParseToken(rawToken);

            audienceUri = new Uri(rawClaims[AudienceLabel]);
            if (audienceUri != null)
            {
                rawClaims.Remove(AudienceLabel);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have an AudienceUri.");
            }

            expires = rawClaims[ExpiresOnLabel];
            if (expires != null)
            {
                rawClaims.Remove(ExpiresOnLabel);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have an expiry time.");
            }

            issuer = rawClaims[IssuerLabel];
            if (issuer != null)
            {
                rawClaims.Remove(IssuerLabel);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have an Issuer");
            }

            signature = rawClaims[Digest256Label];
            if (signature != null)
            {
                rawClaims.Remove(Digest256Label);
            }
            else
            {
                throw new InvalidTokenReceivedException("Then incoming token does not have a signature");
            }

            List<Claim> claims = DecodeClaims(issuer, rawClaims);

            SimpleWebToken swt = new SimpleWebToken(audienceUri, issuer, DecodeExpiry(expires), claims, signature, unsignedString);
            return swt;
        }