Example #1
0
        /// <summary>
        /// Verifies the signature of the incoming token.
        /// </summary>
        /// <param name="key">The key used for signing.</param>
        /// <returns>true if the signatures match, false otherwise.</returns>
        public bool SignVerify(SimpleWebToken token, byte[] key)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            var unsignedToken = CreateUnsignedToken(token);

            string verifySignature;

            using (HMACSHA256 signatureAlgorithm = new HMACSHA256(key))
            {
                verifySignature = Convert.ToBase64String(signatureAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken)));
            }

            if (string.CompareOrdinal(verifySignature, token.Signature) == 0)
            {
                return(true);
            }

            return(false);
        }
Example #2
0
        private static void CreateClaims(SimpleWebToken swt, StringBuilder sb)
        {
            var claims = new Dictionary <string, string>();

            foreach (var claim in swt.Claims)
            {
                claims.Add(claim.Type, claim.Value);
            }

            foreach (var kv in claims)
            {
                sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(kv.Key), HttpUtility.UrlEncode(kv.Value));
            }
        }
Example #3
0
        public override SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor)
        {
            var claims   = tokenDescriptor.Subject.Claims;
            var issuer   = tokenDescriptor.TokenIssuerName;
            var audience = tokenDescriptor.AppliesToAddress;
            var key      = (InMemorySymmetricSecurityKey)tokenDescriptor.SigningCredentials.SigningKey;

            var token = new SimpleWebToken(
                new Uri(audience),
                issuer,
                tokenDescriptor.Lifetime.Expires.Value,
                claims.ToList(),
                key);

            return(token);
        }
Example #4
0
        private static string CreateUnsignedToken(SimpleWebToken swt)
        {
            var sb     = new StringBuilder();
            var claims = new Dictionary <string, string>();

            foreach (var claim in swt.Claims)
            {
                claims.Add(claim.Type, claim.Value);
            }

            foreach (var kv in claims)
            {
                sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(kv.Key), HttpUtility.UrlEncode(kv.Value));
            }

            sb.AppendFormat("Issuer={0}&", HttpUtility.UrlEncode(swt.Issuer));
            sb.AppendFormat("Audience={0}&", HttpUtility.UrlEncode(swt.AudienceUri.AbsoluteUri));
            sb.AppendFormat("ExpiresOn={0:0}", swt.ValidTo.ToEpochTime());

            return(sb.ToString());
        }
Example #5
0
        /// <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 override SecurityToken ReadToken(string 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 + SwtConstants.Digest256 + "=";
                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 SecurityTokenValidationException("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 SecurityTokenValidationException("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[SwtConstants.Audience]);
            if (audienceUri != null)
            {
                rawClaims.Remove(SwtConstants.Audience);
            }
            else
            {
                throw new SecurityTokenValidationException("Then incoming token does not have an AudienceUri.");
            }

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

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

            signature = rawClaims[SwtConstants.Digest256];
            if (signature != null)
            {
                rawClaims.Remove(SwtConstants.Digest256);
            }
            else
            {
                throw new SecurityTokenValidationException("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);
        }
Example #6
0
        public override ReadOnlyCollection <ClaimsIdentity> ValidateToken(SecurityToken token)
        {
            SimpleWebToken swt = token as SimpleWebToken;

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

            // check issuer name registry for allowed issuers
            string issuerName = null;

            if (base.Configuration.IssuerNameRegistry != null)
            {
                issuerName = base.Configuration.IssuerNameRegistry.GetIssuerName(token);
                if (string.IsNullOrEmpty(issuerName))
                {
                    throw new SecurityTokenValidationException("Invalid issuer ");
                }
            }

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

            // check audience
            if (base.Configuration.AudienceRestriction.AudienceMode != AudienceUriMode.Never)
            {
                var allowedAudiences = base.Configuration.AudienceRestriction.AllowedAudienceUris;

                if (!allowedAudiences.Any(uri => uri == swt.AudienceUri))
                {
                    throw new AudienceUriValidationFailedException();
                }
            }

            // retrieve signing key
            var clause      = new WebTokenSecurityKeyClause(swt.Issuer);
            var securityKey = Configuration.IssuerTokenResolver.ResolveSecurityKey(clause) as InMemorySymmetricSecurityKey;

            if (securityKey == null)
            {
                throw new SecurityTokenValidationException("No signing key found");
            }


            // TODO
            // check signature
            if (!swt.VerifySignature(securityKey.GetSymmetricKey()))
            {
                throw new SecurityTokenValidationException("Signature verification of the incoming token failed.");
            }



            var id = new ClaimsIdentity("SWT");

            foreach (var claim in swt.Claims)
            {
                claim.Value.Split(',').ToList().ForEach(v => id.AddClaim(new Claim(claim.Type, v, ClaimValueTypes.String, issuerName)));
            }

            return(new List <ClaimsIdentity> {
                id
            }.AsReadOnly());
        }
        /// <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 override SecurityToken ReadToken(string 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 + SwtConstants.Digest256 + "=";
                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 SecurityTokenValidationException("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 SecurityTokenValidationException("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[SwtConstants.Audience]);
            if (audienceUri != null)
            {
                rawClaims.Remove(SwtConstants.Audience);
            }
            else
            {
                throw new SecurityTokenValidationException("Then incoming token does not have an AudienceUri.");
            }

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

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

            signature = rawClaims[SwtConstants.Digest256];
            if (signature != null)
            {
                rawClaims.Remove(SwtConstants.Digest256);
            }
            else
            {
                throw new SecurityTokenValidationException("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>
        /// Verifies the signature of the incoming token.
        /// </summary>
        /// <param name="key">The key used for signing.</param>
        /// <returns>true if the signatures match, false otherwise.</returns>
        public bool SignVerify(SimpleWebToken token, byte[] key)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            var unsignedToken = CreateUnsignedToken(token);

            string verifySignature;
            using (HMACSHA256 signatureAlgorithm = new HMACSHA256(key))
            {
                verifySignature = Convert.ToBase64String(signatureAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken)));
            }

            if (string.CompareOrdinal(verifySignature, token.Signature) == 0)
            {
                return true;
            }

            return false;
        }
        private static void CreateClaims(SimpleWebToken swt, StringBuilder sb)
        {
            var claims = new Dictionary<string, string>();

            foreach (var claim in swt.Claims)
            {
                claims.Add(claim.Type, claim.Value);
            }

            foreach (var kv in claims)
            {
                sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(kv.Key), HttpUtility.UrlEncode(kv.Value));
            }
        }
        public override SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor)
        {
            var claims = tokenDescriptor.Subject.Claims;
            var issuer = tokenDescriptor.TokenIssuerName;
            var audience = tokenDescriptor.AppliesToAddress;
            var key = (InMemorySymmetricSecurityKey)tokenDescriptor.SigningCredentials.SigningKey;

            var token = new SimpleWebToken(
                new Uri(audience),
                issuer,
                tokenDescriptor.Lifetime.Expires.Value,
                claims.ToList(),
                key);

            return token;
        }
        private static string CreateUnsignedToken(SimpleWebToken swt)
        {
            var sb = new StringBuilder();
            var claims = new Dictionary<string, string>();

            foreach (var claim in swt.Claims)
            {
                claims.Add(claim.Type, claim.Value);
            }

            foreach (var kv in claims)
            {
                sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(kv.Key), HttpUtility.UrlEncode(kv.Value));
            }

            sb.AppendFormat("Issuer={0}&", HttpUtility.UrlEncode(swt.Issuer));
            sb.AppendFormat("Audience={0}&", HttpUtility.UrlEncode(swt.AudienceUri.AbsoluteUri));
            sb.AppendFormat("ExpiresOn={0:0}", swt.ValidTo.ToEpochTime());

            return sb.ToString();
        }