すでに報告されています。応答を待っています。(これも必要だと言ってください!)
今のところ、醜い継承者を使用します。ベースには仮想メソッドがなく、さらにヘルパーが必要なためinternal class ConfigureOpenIdConnectOptionsTTL : IPostConfigureOptions<OpenIdConnectOptions>
(ほとんどの場合、再度コピーアンドペースト)、少なくとも「本番環境での遅いredis」は修正されました。
public class DistributedCacheStateDataFormatterTTL:
DistributedCacheStateDataFormatter, ISecureDataFormat<AuthenticationProperties>
{
public static readonly TimeSpan DefaultCacheDuration = TimeSpan.FromMinutes(5);
private readonly IHttpContextAccessor _httpContext;
private readonly string _name;
public DistributedCacheStateDataFormatterTTL(
IHttpContextAccessor httpContext, string name) : base(httpContext, name)
{
_httpContext = httpContext;
_name = name;
}
private string CacheKeyPrefix => "DistributedCacheStateDataFormatter";
private IDistributedCache Cache =>
_httpContext.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();
private IDataProtector Protector =>
_httpContext.HttpContext.RequestServices
.GetRequiredService<IDataProtectionProvider>()
.CreateProtector(CacheKeyPrefix, _name);
string ISecureDataFormat<AuthenticationProperties>
.Protect(AuthenticationProperties data)
{
return ((ISecureDataFormat<AuthenticationProperties>)this).
Protect(data, string.Empty);
}
string ISecureDataFormat<AuthenticationProperties>
.Protect(AuthenticationProperties data, string purpose)
{
var key = Guid.NewGuid().ToString();
var cacheKey = $"{CacheKeyPrefix}-{purpose}-{key}";
var json = JsonConvert.SerializeObject(data, new JsonSerializerSettings()
{
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
});
var options = new DistributedCacheEntryOptions();
if (data.ExpiresUtc.HasValue)
options.SetAbsoluteExpiration(data.ExpiresUtc.Value);
else
options.SetSlidingExpiration(DefaultCacheDuration);
// Rather than encrypt the full AuthenticationProperties
// cache the data and encrypt the key that points to the data
Cache.SetString(cacheKey, json, options);
return Protector.Protect(key);
}
}
internal class ConfigureOpenIdConnectOptionsTTL : IPostConfigureOptions<OpenIdConnectOptions>
{
private string[] _schemes;
private readonly IHttpContextAccessor _httpContextAccessor;
public ConfigureOpenIdConnectOptionsTTL(string[] schemes, IHttpContextAccessor httpContextAccessor)
{
_schemes = schemes ?? throw new ArgumentNullException(nameof(schemes));
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
public void PostConfigure(string name, OpenIdConnectOptions options)
{
// no schemes means configure them all
if (_schemes.Length == 0 || _schemes.Contains(name))
{
options.StateDataFormat = new DistributedCacheStateDataFormatterTTL(_httpContextAccessor, name);
}
}
public static IServiceCollection AddOidcStateDataFormatterCache(
IServiceCollection services,
params string[] schemes)
{
services.RemoveAll<IPostConfigureOptions<OpenIdConnectOptions>>();
services.AddSingleton<IPostConfigureOptions<OpenIdConnectOptions>>(
svcs => new ConfigureOpenIdConnectOptionsTTL(
schemes,
svcs.GetRequiredService<IHttpContextAccessor>())
);
return services;
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加