gpt4 book ai didi

asp.net-core - 如何动态设置 OpenIdConnect 中间件选项的权限?

转载 作者:行者123 更新时间:2023-12-03 13:36:47 26 4
gpt4 key购买 nike

我们有多个租户,他们使用不同的权限(他们自己的,而不仅仅是标准提供商)。虽然我知道如何动态设置 clientId 和 secret,但我不知道如何设置权限。它在启动期间设置一次,之后无法更改(或者看起来如此)。

由于我们有很 Multi-Tenancy ,我们不想在启动时全部注册,也不想在添加租户时要求重新启动。

有什么建议我可以怎么做吗?我很想使用现有的中间件,但如果不可能,我可以自己编写。

感谢任何建议!

最佳答案

虽然有点棘手,但绝对有可能。这是一个使用 MSFT OIDC 处理程序、自定义监视器和基于路径的租户解析的简化示例:

实现租户解析逻辑。例如:

public class TenantProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;

public TenantProvider(IHttpContextAccessor httpContextAccessor)
=> _httpContextAccessor = httpContextAccessor;

public string GetCurrentTenant()
{
// This sample uses the path base as the tenant.
// You can replace that by your own logic.
string tenant = _httpContextAccessor.HttpContext.Request.PathBase;
if (string.IsNullOrEmpty(tenant))
{
tenant = "default";
}

return tenant;
}
}

public void Configure(IApplicationBuilder app)
{
app.Use(next => context =>
{
// This snippet uses a hardcoded resolution logic.
// In a real world app, you'd want to customize that.
if (context.Request.Path.StartsWithSegments("/fabrikam", out PathString path))
{
context.Request.PathBase = "/fabrikam";
context.Request.Path = path;
}

return next(context);
});

app.UseAuthentication();

app.UseMvc();
}

实现自定义 IOptionsMonitor<OpenIdConnectOptions> :

public class OpenIdConnectOptionsProvider : IOptionsMonitor<OpenIdConnectOptions>
{
private readonly ConcurrentDictionary<(string name, string tenant), Lazy<OpenIdConnectOptions>> _cache;
private readonly IOptionsFactory<OpenIdConnectOptions> _optionsFactory;
private readonly TenantProvider _tenantProvider;

public OpenIdConnectOptionsProvider(
IOptionsFactory<OpenIdConnectOptions> optionsFactory,
TenantProvider tenantProvider)
{
_cache = new ConcurrentDictionary<(string, string), Lazy<OpenIdConnectOptions>>();
_optionsFactory = optionsFactory;
_tenantProvider = tenantProvider;
}

public OpenIdConnectOptions CurrentValue => Get(Options.DefaultName);

public OpenIdConnectOptions Get(string name)
{
var tenant = _tenantProvider.GetCurrentTenant();

Lazy<OpenIdConnectOptions> Create() => new Lazy<OpenIdConnectOptions>(() => _optionsFactory.Create(name));
return _cache.GetOrAdd((name, tenant), _ => Create()).Value;
}

public IDisposable OnChange(Action<OpenIdConnectOptions, string> listener) => null;
}

实现自定义 IConfigureNamedOptions<OpenIdConnectOptions> :

public class OpenIdConnectOptionsInitializer : IConfigureNamedOptions<OpenIdConnectOptions>
{
private readonly IDataProtectionProvider _dataProtectionProvider;
private readonly TenantProvider _tenantProvider;

public OpenIdConnectOptionsInitializer(
IDataProtectionProvider dataProtectionProvider,
TenantProvider tenantProvider)
{
_dataProtectionProvider = dataProtectionProvider;
_tenantProvider = tenantProvider;
}

public void Configure(string name, OpenIdConnectOptions options)
{
if (!string.Equals(name, OpenIdConnectDefaults.AuthenticationScheme, StringComparison.Ordinal))
{
return;
}

var tenant = _tenantProvider.GetCurrentTenant();

// Create a tenant-specific data protection provider to ensure
// encrypted states can't be read/decrypted by the other tenants.
options.DataProtectionProvider = _dataProtectionProvider.CreateProtector(tenant);

// Other tenant-specific options like options.Authority can be registered here.
}

public void Configure(OpenIdConnectOptions options)
=> Debug.Fail("This infrastructure method shouldn't be called.");
}

在 DI 容器中注册服务:

public void ConfigureServices(IServiceCollection services)
{
// ...

// Register the OpenID Connect handler.
services.AddAuthentication()
.AddOpenIdConnect();

services.AddSingleton<TenantProvider>();
services.AddSingleton<IOptionsMonitor<OpenIdConnectOptions>, OpenIdConnectOptionsProvider>();
services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectOptionsInitializer>();
}

关于asp.net-core - 如何动态设置 OpenIdConnect 中间件选项的权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52955238/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com