示例#1
0
        private static bool AreIssuerSigningKeyResolversEqual(IssuerSigningKeyResolver keyResolver1, IssuerSigningKeyResolver keyResolver2, CompareContext context)
        {
            var localContext = new CompareContext(context);

            ContinueCheckingEquality(keyResolver1, keyResolver2, context);
            return(context.Merge(localContext));
        }
示例#2
0
        public void ShouldSetSecurityKeyResolver()
        {
            // Given
            var options  = new TokenValidationParameters();
            var resolver = new IssuerSigningKeyResolver(
                (w, x, y, z) =>
                new[] { new SymmetricSecurityKey(Encoding.UTF8.GetBytes("23j79h675s78T904gldUt0M5SftPg50H3W85s5A8u68zUV4AIJ")) });
            var validator = new IssuerSigningKeyValidator((x, y, z) => true);

            // When
            options.WithIssuerKeyValidation(resolver, validator);

            // Then
            Assert.True(options.ValidateIssuerSigningKey);
            Assert.Equal(resolver, options.IssuerSigningKeyResolver);
            Assert.Equal(validator, options.IssuerSigningKeyValidator);
        }
        public static TokenValidationParameters WithIssuerKeyValidation(this TokenValidationParameters parameters,
                                                                        IssuerSigningKeyResolver securityKeyResolver, IssuerSigningKeyValidator keyValidator = null)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            if (securityKeyResolver == null)
            {
                throw new ArgumentNullException(nameof(securityKeyResolver));
            }


            parameters.ValidateIssuerSigningKey  = true;
            parameters.IssuerSigningKeyResolver  = securityKeyResolver;
            parameters.IssuerSigningKeyValidator = keyValidator;

            return(parameters);
        }
示例#4
0
 public void WithIssuerKeyValidationShouldValidateInput2(TokenValidationParameters options, IssuerSigningKeyResolver securityKeyResolver)
 {
     Assert.Throws <ArgumentNullException>(() => options.WithIssuerKeyValidation(securityKeyResolver));
 }
示例#5
0
        /// <summary>
        /// Constructor
        /// 构造函数
        /// </summary>
        /// <param name="services">Dependency injection services</param>
        /// <param name="sslOnly">SSL only?</param>
        /// <param name="section">Configuration section</param>
        /// <param name="secureManager">Secure manager</param>
        /// <param name="issuerSigningKeyResolver">Issuer signing key resolver</param>
        /// <param name="tokenDecryptionKeyResolver">Token decryption key resolver</param>
        public JwtService(IServiceCollection services,
                          bool sslOnly,
                          IConfigurationSection section,
                          Func <string, string>?secureManager = null,
                          IssuerSigningKeyResolver?issuerSigningKeyResolver     = null,
                          TokenDecryptionKeyResolver?tokenDecryptionKeyResolver = null)
        {
            // Jwt section is required
            if (!section.Exists())
            {
                throw new ArgumentNullException(nameof(section), "No Section");
            }

            defaultIssuer   = section.GetValue <string>("DefaultIssuer") ?? DefaultIssuer;
            defaultAudience = section.GetValue <string>("DefaultAudience") ?? "All";

            validIssuer  = section.GetValue <string>("ValidIssuer");
            validIssuers = section.GetSection("ValidIssuers").Get <IEnumerable <string> >();
            if (string.IsNullOrEmpty(validIssuer))
            {
                validIssuer = defaultIssuer;
            }

            validAudience  = section.GetValue <string>("ValidAudience");
            validAudiences = section.GetSection("ValidAudiences").Get <IEnumerable <string> >();
            if (string.IsNullOrEmpty(validAudience) && validAudiences == null)
            {
                validAudience = defaultAudience;
            }

            // Whether validate audience
            var validateAudience = section.GetValue <bool?>("ValidateAudience");

            // Hash algorithms
            securityAlgorithms = section.GetValue("SecurityAlgorithms", SecurityAlgorithms.RsaSha512Signature);

            // Default 30 minutes
            AccessTokenMinutes = section.GetValue("AccessTokenMinutes", 30);

            // Default 90 days
            RefreshTokenDays = section.GetValue("RefreshTokenDays", 90);

            // https://stackoverflow.com/questions/53487247/encrypting-jwt-security-token-supported-algorithms
            // AES256, 256 / 8 = 32 bytes
            var encryptionKeyPlain = CryptographyUtils.UnsealData(section.GetValue <string>("EncryptionKey"), secureManager);

            // RSA crypto provider
            crypto = new RSACrypto(section, secureManager);

            // Default signing key resolver
            this.issuerSigningKeyResolver = (token, securityToken, kid, validationParameters) =>
            {
                if (issuerSigningKeyResolver == null)
                {
                    return(new List <RsaSecurityKey> {
                        new RsaSecurityKey(crypto.RSA)
                        {
                            KeyId = kid
                        }
                    });
                }

                var keys = issuerSigningKeyResolver(token, securityToken, kid, validationParameters);
                if (!keys.Any())
                {
                    keys = keys.Append(new RsaSecurityKey(crypto.RSA)
                    {
                        KeyId = kid
                    });
                }

                return(keys);
            };

            this.tokenDecryptionKeyResolver = (token, securityToken, kid, validationParameters) =>
            {
                if (tokenDecryptionKeyResolver == null)
                {
                    return(new List <SymmetricSecurityKey> {
                        new SymmetricSecurityKey(Encoding.UTF8.GetBytes(encryptionKeyPlain))
                        {
                            KeyId = kid
                        }
                    });
                }

                var keys = tokenDecryptionKeyResolver(token, securityToken, kid, validationParameters);
                if (!keys.Any())
                {
                    keys = keys.Append(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(encryptionKeyPlain))
                    {
                        KeyId = kid
                    });
                }

                return(keys);
            };

            // Adding Authentication
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            {
                // Is SSL only
                options.RequireHttpsMetadata = sslOnly;

                // Useful forwarding the JWT in an outgoing request
                // https://stackoverflow.com/questions/57057749/what-is-the-purpose-of-jwtbeareroptions-savetoken-property-in-asp-net-core-2-0
                options.SaveToken = false;

                // Token validation parameters
                options.TokenValidationParameters = CreateValidationParameters();
                if (validateAudience != null)
                {
                    options.TokenValidationParameters.ValidateAudience = validateAudience.Value;
                }
            });
        }