コード例 #1
0
        /// <summary>
        /// Creates security token.
        /// </summary>
        /// <param name="tokenDescriptor">The token descriptor.</param>
        /// <returns>Security token.</returns>
        public override SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor)
        {
            if (tokenDescriptor == null)
            {
                throw new ArgumentNullException("tokenDescriptor");
            }

            // See details in Json Web Token specification.
            var seconds = (tokenDescriptor.Lifetime.Expires - tokenDescriptor.Lifetime.Created) ?? new TimeSpan(0, 0, 3600);
            var header  = new JwtHeaderSegment();
            var claims  = new JwtClaimsSegment(
                tokenDescriptor.TokenIssuerName,
                tokenDescriptor.AppliesToAddress,
                DateTime.UtcNow,
                DateTime.UtcNow + seconds,
                tokenDescriptor.Subject.Claims
                );

            // See details in Json Web Signature specification.
            var key             = (InMemorySymmetricSecurityKey)tokenDescriptor.SigningCredentials.SigningKey;
            var mac             = new HMACSHA256(key.GetSymmetricKey());
            var hash            = mac.ComputeHash(Encoding.UTF8.GetBytes(JsonWebToken.GetSigningInput(header, claims)));
            var jwsCryptoOutput = JwtTokenUtility.Base64UrlEncode(hash);

            return(new JsonWebToken(header, claims, jwsCryptoOutput));
        }
コード例 #2
0
ファイル: JsonWebToken.cs プロジェクト: me-viper/OAuthJwt
        /// <summary>
        /// Retrieves token signing input.
        /// </summary>
        /// <param name="header">JWT header section.</param>
        /// <param name="payload">JWT payload section.</param>
        /// <returns>Signing input.</returns>
        /// <remarks>For details refer to Json Web Signature specification.</remarks>
        internal static string GetSigningInput(JwtHeaderSegment header, JwtClaimsSegment payload)
        {
            var decodedJwsHeaderInput = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header));
            var jwsHeaderInput        = JwtTokenUtility.Base64UrlEncode(decodedJwsHeaderInput);

            var decodedJwsPayloadInput = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload));
            var jwsPaloadInput         = JwtTokenUtility.Base64UrlEncode(decodedJwsPayloadInput);

            return(string.Format("{0}.{1}", jwsHeaderInput, jwsPaloadInput));
        }
コード例 #3
0
        /// <summary>
        /// Validates security token.
        /// </summary>
        /// <param name="token">Security token.</param>
        /// <returns><see cref="ClaimsIdentityCollection"/> stored inside security token.</returns>
        public override ClaimsIdentityCollection ValidateToken(SecurityToken token)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }

            var jwt = (JsonWebToken)token;

            // Stage 1: Validating token signature.
            InMemorySymmetricSecurityKey key = null;

            try
            {
                key = (InMemorySymmetricSecurityKey)Configuration.IssuerTokenResolver.ResolveSecurityKey(
                    new KeyNameIdentifierClause(jwt.ClaimsSection.Issuer)
                    );
            }
            catch (Exception)
            {
                throw new InvalidOperationException("Failed to resolver isser's key");
            }

            // Signature is checked according to JSON Web Signature specification.
            var mac = new HMACSHA256(key.GetSymmetricKey());

            var cryptoInput = JwtTokenUtility.Base64UrlEncode(
                mac.ComputeHash(Encoding.UTF8.GetBytes(jwt.GetSigningInput()))
                );

            if (!string.Equals(jwt.Signature, cryptoInput, StringComparison.Ordinal))
            {
                throw new SignatureVerificationFailedException("Token contents do not match signature.");
            }

            // Stage 2: Checking whether token is up to date.
            var utcNow = DateTime.UtcNow;

            if (utcNow + Configuration.MaxClockSkew < token.ValidFrom)
            {
                throw new SecurityTokenNotYetValidException();
            }

            if (utcNow + Configuration.MaxClockSkew > token.ValidTo)
            {
                throw new SecurityTokenExpiredException();
            }

            // Stage 3: Checking whether we should even bother talking to specified RP.
            if (Configuration.AudienceRestriction.AudienceMode != AudienceUriMode.Never)
            {
                if (string.IsNullOrWhiteSpace(jwt.ClaimsSection.Audience))
                {
                    throw new AudienceUriValidationFailedException("Token does not contain Audience uri.");
                }

                var uri = new Uri(jwt.ClaimsSection.Audience);

                if (!Configuration.AudienceRestriction.AllowedAudienceUris.Contains(uri))
                {
                    throw new AudienceUriValidationFailedException(
                              string.Format("Uri {0} is not spceified in audience uri section", uri.ToString())
                              );
                }
            }

            // Stage 4: If configured, let WIF check "Replay Token" attack.
            if (Configuration.DetectReplayedTokens)
            {
                DetectReplayedTokens(token);
            }

            // Stage 5: Extracting claims from security token.
            var inputIdentity = new ClaimsIdentity(jwt.ClaimsSection.Claims);

            // Stage 6: If configured, saving bootstrap token that may be
            // used by RP for delegation (ActAs and BehalfOf calls).
            if (Configuration.SaveBootstrapTokens)
            {
                inputIdentity.BootstrapToken = token;
            }

            return(new ClaimsIdentityCollection(new [] { inputIdentity }));
        }