private static bool AreIssuerSigningKeyResolversEqual(IssuerSigningKeyResolver keyResolver1, IssuerSigningKeyResolver keyResolver2, CompareContext context) { var localContext = new CompareContext(context); ContinueCheckingEquality(keyResolver1, keyResolver2, context); return(context.Merge(localContext)); }
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); }
public void WithIssuerKeyValidationShouldValidateInput2(TokenValidationParameters options, IssuerSigningKeyResolver securityKeyResolver) { Assert.Throws <ArgumentNullException>(() => options.WithIssuerKeyValidation(securityKeyResolver)); }
/// <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; } }); }