1- using System . Collections . ObjectModel ;
1+ using System . Collections . Generic ;
2+ using System . Collections . ObjectModel ;
23using System . Globalization ;
34using System . Runtime . InteropServices ;
45using System . Text . Json ;
1112using Microsoft . Extensions . Options ;
1213using Microsoft . Win32 ;
1314using NetDevPack . Security . Jwt . Core . Interfaces ;
15+ using NetDevPack . Security . Jwt . Core . Jwa ;
1416using NetDevPack . Security . Jwt . Core . Model ;
1517
1618namespace NetDevPack . Security . Jwt . Core . DefaultStore ;
@@ -52,13 +54,13 @@ public DataProtectionStore(
5254 _memoryCache = memoryCache ;
5355 _dataProtector = provider . CreateProtector ( nameof ( KeyMaterial ) ) ; ;
5456 }
55- public Task Store ( KeyMaterial securityParamteres )
57+ public Task Store ( KeyMaterial securityParameters )
5658 {
57- var possiblyEncryptedKeyElement = _dataProtector . Protect ( JsonSerializer . Serialize ( securityParamteres ) ) ;
59+ var possiblyEncryptedKeyElement = _dataProtector . Protect ( JsonSerializer . Serialize ( securityParameters ) ) ;
5860
5961 // build the <key> element
6062 var keyElement = new XElement ( Name ,
61- new XAttribute ( IdAttributeName , securityParamteres . Id ) ,
63+ new XAttribute ( IdAttributeName , securityParameters . Id ) ,
6264 new XAttribute ( VersionAttributeName , 1 ) ,
6365 new XElement ( CreationDateElementName , DateTimeOffset . UtcNow ) ,
6466 new XElement ( ActivationDateElementName , DateTimeOffset . UtcNow ) ,
@@ -68,7 +70,7 @@ public Task Store(KeyMaterial securityParamteres)
6870 possiblyEncryptedKeyElement ) ) ;
6971
7072 // Persist it to the underlying repository and trigger the cancellation token.
71- var friendlyName = string . Format ( CultureInfo . InvariantCulture , "key-{0}" , securityParamteres . KeyId ) ;
73+ var friendlyName = string . Format ( CultureInfo . InvariantCulture , "key-{0}" , securityParameters . KeyId ) ;
7274 KeyRepository . StoreElement ( keyElement , friendlyName ) ;
7375 ClearCache ( ) ;
7476
@@ -77,19 +79,21 @@ public Task Store(KeyMaterial securityParamteres)
7779
7880
7981
80- public async Task < KeyMaterial > GetCurrent ( )
82+ public async Task < KeyMaterial > GetCurrent ( JwtKeyType jwtKeyType = JwtKeyType . Jws )
8183 {
82- if ( ! _memoryCache . TryGetValue ( JwkContants . CurrentJwkCache , out KeyMaterial keyMaterial ) )
84+ var cacheKey = JwkContants . CurrentJwkCache + jwtKeyType ;
85+
86+ if ( ! _memoryCache . TryGetValue ( cacheKey , out KeyMaterial keyMaterial ) )
8387 {
84- var keys = await GetLastKeys ( 1 ) ;
88+ var keys = await GetLastKeys ( 1 , jwtKeyType ) ;
8589 keyMaterial = keys . FirstOrDefault ( ) ;
8690 // Set cache options.
8791 var cacheEntryOptions = new MemoryCacheEntryOptions ( )
8892 // Keep in cache for this time, reset time if accessed.
8993 . SetSlidingExpiration ( _options . Value . CacheTime ) ;
9094
9195 if ( keyMaterial != null )
92- _memoryCache . Set ( JwkContants . CurrentJwkCache , keyMaterial , cacheEntryOptions ) ;
96+ _memoryCache . Set ( cacheKey , keyMaterial , cacheEntryOptions ) ;
9397 }
9498
9599 return keyMaterial ;
@@ -146,10 +150,11 @@ private IReadOnlyCollection<KeyMaterial> GetKeys()
146150 }
147151
148152
149- public Task < ReadOnlyCollection < KeyMaterial > > GetLastKeys ( int quantity = 5 )
153+ public Task < ReadOnlyCollection < KeyMaterial > > GetLastKeys ( int quantity = 5 , JwtKeyType ? jwtKeyType = null )
150154 {
155+ var cacheKey = JwkContants . JwksCache + jwtKeyType ;
151156
152- if ( ! _memoryCache . TryGetValue ( JwkContants . JwksCache , out IReadOnlyCollection < KeyMaterial > keys ) )
157+ if ( ! _memoryCache . TryGetValue ( cacheKey , out IReadOnlyCollection < KeyMaterial > keys ) )
153158 {
154159 keys = GetKeys ( ) ;
155160
@@ -159,13 +164,20 @@ public Task<ReadOnlyCollection<KeyMaterial>> GetLastKeys(int quantity = 5)
159164 . SetSlidingExpiration ( _options . Value . CacheTime ) ;
160165
161166 if ( keys . Any ( ) )
162- _memoryCache . Set ( JwkContants . JwksCache , keys , cacheEntryOptions ) ;
167+ {
168+ keys = keys
169+ . Where ( s => jwtKeyType == null || s . Use == ( jwtKeyType == JwtKeyType . Jws ? "sig" : "enc" ) )
170+ . OrderByDescending ( s => s . CreationDate )
171+ . ToList ( ) . AsReadOnly ( ) ;
172+
173+ _memoryCache . Set ( cacheKey , keys , cacheEntryOptions ) ;
174+ }
163175 }
164176
165177 return Task . FromResult ( keys
166- . OrderByDescending ( s => s . CreationDate )
167- . ToList ( )
168- . AsReadOnly ( ) ) ;
178+ . GroupBy ( s => s . Use )
179+ . SelectMany ( g => g . Take ( quantity ) )
180+ . ToList ( ) . AsReadOnly ( ) ) ;
169181 }
170182
171183 public Task < KeyMaterial > Get ( string keyId )
@@ -185,10 +197,10 @@ public async Task Clear()
185197
186198 public async Task Revoke ( KeyMaterial keyMaterial , string reason = null )
187199 {
188- if ( keyMaterial == null )
200+ if ( keyMaterial == null )
189201 return ;
190-
191- var keys = await GetLastKeys ( ) ;
202+
203+ var keys = await GetLastKeys ( jwtKeyType : keyMaterial . Use . Equals ( "sig" , StringComparison . InvariantCultureIgnoreCase ) ? JwtKeyType . Jws : JwtKeyType . Jwe ) ;
192204 var key = keys . First ( f => f . Id == keyMaterial . Id ) ;
193205
194206 if ( key is { IsRevoked : true } )
@@ -214,7 +226,11 @@ public async Task Revoke(KeyMaterial keyMaterial, string reason = null)
214226 private void ClearCache ( )
215227 {
216228 _memoryCache . Remove ( JwkContants . JwksCache ) ;
229+ _memoryCache . Remove ( JwkContants . JwksCache + JwtKeyType . Jws ) ;
230+ _memoryCache . Remove ( JwkContants . JwksCache + JwtKeyType . Jwe ) ;
217231 _memoryCache . Remove ( JwkContants . CurrentJwkCache ) ;
232+ _memoryCache . Remove ( JwkContants . CurrentJwkCache + JwtKeyType . Jws ) ;
233+ _memoryCache . Remove ( JwkContants . CurrentJwkCache + JwtKeyType . Jwe ) ;
218234 }
219235
220236 /// <summary>
0 commit comments