#### [Abblix\.SecurityEvents](https://www.abblix.com/en/docs/api/abblix-securityevents 'index')
### [Abblix\.SecurityEvents\.Infrastructure](https://www.abblix.com/en/docs/api/abblix-securityevents/Abblix.SecurityEvents.Infrastructure 'Abblix\.SecurityEvents\.Infrastructure')

## JwksIssuerKeyResolver Class

Resolves issuers' verification keys from their published JWK Set documents, cached so the hot
path of validation performs no network I/O\.

```csharp
public sealed class JwksIssuerKeyResolver : Abblix.SecurityEvents.Abstractions.IIssuerKeyResolver
```

Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') → JwksIssuerKeyResolver

Implements [IIssuerKeyResolver](https://www.abblix.com/en/docs/api/abblix-securityevents/Abblix.SecurityEvents.Abstractions.IIssuerKeyResolver 'Abblix\.SecurityEvents\.Abstractions\.IIssuerKeyResolver')

### Remarks

A key rollover is noticed two ways: the cache lifetime expires, or a token names a "kid" the
cached set lacks - the earliest possible signal - which forces one refetch, rate-limited so a
flood of bogus identifiers cannot turn it into hammering the issuer. Concurrent resolutions
may fetch the same document twice; the copies are identical and the last write wins, which is
cheaper than a lock on every validation.

A fetch failure propagates as its exception rather than as an empty key set: empty means "this
issuer is not trusted", a verdict about the token, while an unreachable JWKS endpoint is an
infrastructure failure the delivery endpoint should answer with a retryable status, not with
"invalid key".
### Constructors

## JwksIssuerKeyResolver\(IHttpClientFactory, TimeProvider, IOptions\<JwksKeyResolutionOptions\>\) Constructor {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.JwksIssuerKeyResolver(System.Net.Http.IHttpClientFactory,System.TimeProvider,Microsoft.Extensions.Options.IOptions_Abblix.SecurityEvents.Infrastructure.JwksKeyResolutionOptions_)}

Resolves issuers' verification keys from their published JWK Set documents, cached so the hot
path of validation performs no network I/O\.

```csharp
public JwksIssuerKeyResolver(System.Net.Http.IHttpClientFactory httpClientFactory, System.TimeProvider clock, Microsoft.Extensions.Options.IOptions<Abblix.SecurityEvents.Infrastructure.JwksKeyResolutionOptions> options);
```
#### Parameters

###### `httpClientFactory` [System\.Net\.Http\.IHttpClientFactory](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.ihttpclientfactory 'System\.Net\.Http\.IHttpClientFactory') {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.JwksIssuerKeyResolver(System.Net.Http.IHttpClientFactory,System.TimeProvider,Microsoft.Extensions.Options.IOptions_Abblix.SecurityEvents.Infrastructure.JwksKeyResolutionOptions_).httpClientFactory}

Supplies the HTTP client, created per fetch under [HttpClientName](https://www.abblix.com/en/docs/api/abblix-securityevents/Abblix.SecurityEvents.Infrastructure.JwksTransport#Abblix.SecurityEvents.Infrastructure.JwksTransport.HttpClientName 'Abblix\.SecurityEvents\.Infrastructure\.JwksTransport\.HttpClientName') so a host can
configure the named client \- timeouts, proxy, resilience \- without touching this type\.

###### `clock` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.JwksIssuerKeyResolver(System.Net.Http.IHttpClientFactory,System.TimeProvider,Microsoft.Extensions.Options.IOptions_Abblix.SecurityEvents.Infrastructure.JwksKeyResolutionOptions_).clock}

Drives cache expiry and the rollover cooldown\.

###### `options` [Microsoft\.Extensions\.Options\.IOptions&lt;](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.options.ioptions-1 'Microsoft\.Extensions\.Options\.IOptions\`1')[JwksKeyResolutionOptions](https://www.abblix.com/en/docs/api/abblix-securityevents/Abblix.SecurityEvents.Infrastructure.JwksKeyResolutionOptions 'Abblix\.SecurityEvents\.Infrastructure\.JwksKeyResolutionOptions')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.options.ioptions-1 'Microsoft\.Extensions\.Options\.IOptions\`1') {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.JwksIssuerKeyResolver(System.Net.Http.IHttpClientFactory,System.TimeProvider,Microsoft.Extensions.Options.IOptions_Abblix.SecurityEvents.Infrastructure.JwksKeyResolutionOptions_).options}

Where key sets live and how long they answer from cache\.

### Remarks

A key rollover is noticed two ways: the cache lifetime expires, or a token names a "kid" the
cached set lacks - the earliest possible signal - which forces one refetch, rate-limited so a
flood of bogus identifiers cannot turn it into hammering the issuer. Concurrent resolutions
may fetch the same document twice; the copies are identical and the last write wins, which is
cheaper than a lock on every validation.

A fetch failure propagates as its exception rather than as an empty key set: empty means "this
issuer is not trusted", a verdict about the token, while an unreachable JWKS endpoint is an
infrastructure failure the delivery endpoint should answer with a retryable status, not with
"invalid key".
### Methods

## JwksIssuerKeyResolver\.ResolveSigningKeysAsync\(string, string, CancellationToken\) Method {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.ResolveSigningKeysAsync(string,string,System.Threading.CancellationToken)}

Resolves the signature verification keys of an issuer\.

```csharp
public System.Collections.Generic.IAsyncEnumerable<Abblix.Jwt.JsonWebKey> ResolveSigningKeysAsync(string issuer, string? keyId=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
```
#### Parameters

###### `issuer` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.ResolveSigningKeysAsync(string,string,System.Threading.CancellationToken).issuer}

The issuer as its tokens spell it in "iss"\.

###### `keyId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.ResolveSigningKeysAsync(string,string,System.Threading.CancellationToken).keyId}

The "kid" the token's header names, when it names one\. This is the key\-rollover signal: a
caching implementation that holds keys for the issuer but none under this identifier knows
its copy predates a rotation and refreshes before answering, instead of failing a token
signed with a key newer than the cache\.

###### `cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.SecurityEvents.Infrastructure.JwksIssuerKeyResolver.ResolveSigningKeysAsync(string,string,System.Threading.CancellationToken).cancellationToken}

Cancels retrieval mid\-flight\.

Implements [ResolveSigningKeysAsync\(string, string, CancellationToken\)](https://www.abblix.com/en/docs/api/abblix-securityevents/Abblix.SecurityEvents.Abstractions.IIssuerKeyResolver#Abblix.SecurityEvents.Abstractions.IIssuerKeyResolver.ResolveSigningKeysAsync(string,string,System.Threading.CancellationToken) 'Abblix\.SecurityEvents\.Abstractions\.IIssuerKeyResolver\.ResolveSigningKeysAsync\(string, string, System\.Threading\.CancellationToken\)')

#### Returns
[System\.Collections\.Generic\.IAsyncEnumerable&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1 'System\.Collections\.Generic\.IAsyncEnumerable\`1')[JsonWebKey](https://www.abblix.com/en/docs/api/abblix-jwt/Abblix.Jwt.JsonWebKey 'Abblix\.Jwt\.JsonWebKey')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1 'System\.Collections\.Generic\.IAsyncEnumerable\`1')  
The issuer's current verification keys; empty when the issuer is not trusted\.
