-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathTokenIssuerCache.cs
64 lines (54 loc) · 1.91 KB
/
TokenIssuerCache.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Protocols;
using Microsoft.Extensions.Options;
namespace Digdir.Domain.Dialogporten.GraphQL.Common.Authentication;
public interface ITokenIssuerCache
{
public Task<string?> GetIssuerForScheme(string schemeName);
}
public sealed class TokenIssuerCache : ITokenIssuerCache, IDisposable
{
private readonly Dictionary<string, string> _issuerMappings = new();
private readonly SemaphoreSlim _initializationSemaphore = new(1, 1);
private bool _initialized;
private readonly IReadOnlyCollection<JwtBearerTokenSchemasOptions> _jwtTokenSchemas;
public TokenIssuerCache(IOptions<GraphQlSettings> apiSettings)
{
_jwtTokenSchemas = apiSettings
.Value
.Authentication
.JwtBearerTokenSchemas
?? throw new ArgumentException("JwtBearerTokenSchemas is required.");
}
public async Task<string?> GetIssuerForScheme(string schemeName)
{
await EnsureInitializedAsync();
return _issuerMappings.TryGetValue(schemeName, out var issuer)
? issuer : null;
}
private async Task EnsureInitializedAsync()
{
if (_initialized) return;
await _initializationSemaphore.WaitAsync();
if (_initialized) return;
try
{
foreach (var schema in _jwtTokenSchemas)
{
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(
schema.WellKnown, new OpenIdConnectConfigurationRetriever());
var config = await configManager.GetConfigurationAsync();
_issuerMappings[schema.Name] = config.Issuer;
}
_initialized = true;
}
finally
{
_initializationSemaphore.Release();
}
}
public void Dispose()
{
_initializationSemaphore.Dispose();
}
}