@@ -6,21 +6,72 @@ public static class AuthenticationExtension
66 public static IServiceCollection AddJwtAuthentication ( this IServiceCollection services )
77 {
88 var serviceProvider = services . BuildServiceProvider ( ) ;
9- var secretRepository = serviceProvider . GetRequiredService < ISecretCollection > ( ) ;
9+ var accessor = serviceProvider . GetRequiredService < IHttpContextAccessor > ( ) ;
1010
11- var secret = secretRepository . GetSecretAsync ( )
12- . GetAwaiter ( )
13- . GetResult ( ) ;
14-
15- var publicKey = Common . Utilities . RsaHelper . CreateSecurityKeyFromPublicKey ( secret . PublicKey ) ;
1611 var validationParameters = new TokenValidationParameters
1712 {
1813 ValidateIssuer = false ,
1914 ValidateAudience = false ,
2015 ValidateLifetime = true ,
2116 ValidateIssuerSigningKey = true ,
22- IssuerSigningKey = publicKey ,
23- ClockSkew = TimeSpan . Zero
17+ ClockSkew = TimeSpan . FromSeconds ( 30 ) ,
18+ IssuerSigningKeyResolver = ( token , _ , kid , _ ) =>
19+ {
20+ var context = accessor . HttpContext ;
21+ if ( context is null || string . IsNullOrWhiteSpace ( token ) )
22+ return [ ] ;
23+
24+ var secretCollection = context . RequestServices . GetRequiredService < ISecretCollection > ( ) ;
25+ var realmCollection = context . RequestServices . GetRequiredService < IRealmCollection > ( ) ;
26+
27+ var jsonWebToken = new Microsoft . IdentityModel . JsonWebTokens . JsonWebToken ( token ) ;
28+ var realmId = jsonWebToken . Claims . FirstOrDefault ( claim => claim . Type == Infrastructure . Constants . IdentityClaimNames . RealmId ) ? . Value ;
29+
30+ if ( string . IsNullOrWhiteSpace ( realmId ) )
31+ {
32+ var realmName = jsonWebToken . Claims . FirstOrDefault ( claim => claim . Type == Infrastructure . Constants . IdentityClaimNames . Realm ) ? . Value ;
33+
34+ if ( string . IsNullOrWhiteSpace ( realmName ) )
35+ return [ ] ;
36+
37+ var realmFilters = RealmFilters . WithSpecifications ( )
38+ . WithName ( realmName )
39+ . Build ( ) ;
40+
41+ var realms = realmCollection
42+ . GetRealmsAsync ( realmFilters , context . RequestAborted )
43+ . GetAwaiter ( )
44+ . GetResult ( ) ;
45+
46+ realmId = realms . FirstOrDefault ( ) ? . Id ;
47+ }
48+
49+ if ( string . IsNullOrWhiteSpace ( realmId ) )
50+ return [ ] ;
51+
52+ var secretFilters = SecretFilters . WithSpecifications ( )
53+ . WithRealm ( realmId )
54+ . WithCanValidate ( )
55+ . Build ( ) ;
56+
57+ var secrets = secretCollection
58+ . GetSecretsAsync ( secretFilters , context . RequestAborted )
59+ . GetAwaiter ( )
60+ . GetResult ( ) ;
61+
62+ if ( ! string . IsNullOrWhiteSpace ( kid ) )
63+ {
64+ secrets = [ .. secrets . Where ( secret => secret . Id == kid ) ] ;
65+ }
66+
67+ return [ .. secrets . Select ( secret =>
68+ {
69+ var key = Common . Utilities . RsaHelper . CreateSecurityKeyFromPublicKey ( secret . PublicKey ) ;
70+ key . KeyId = secret . Id ;
71+
72+ return key ;
73+ } ) ] ;
74+ }
2475 } ;
2576
2677 var builder = services . AddAuthentication ( options =>
0 commit comments