asp.net-core – openid connect – 在登录期间识别租户
我有一个多租户(单一数据库)应用程序,允许跨不同租户使用相同的用户名/电子邮件.
在登录时(隐含流程)我如何识别租户?我想到了以下可能性: >在注册时询问用户帐户slug(公司/租户slug),并在登录期间用户应提供slug以及用户名和密码. 但是在open id请求中没有参数来发送slug. 这种做法好吗? 编辑: 也尝试制作路线param的slug部分 .EnableTokenEndpoint("/connect/{slug}/token"); 但openiddict不支持这一点. 解决方法
McGuire建议的方法将与OpenIddict一起使用(您可以通过OpenIdConnectRequest.AcrValues访问acr_values属性)但它不是推荐的选项(从安全角度看它并不理想:因为发行者对所有租户来说都是相同的,所以他们最终共享相同的签名密钥).
相反,考虑为每个租户运行一个发行者.为此,您至少有两个选择: >尝试OrchardCore’s OpenID module:它基于OpenIddict,本机支持多租户.它仍处于测试阶段,但它正在积极开发中. 以下是第二个选项的简化示例,使用自定义监视器和基于路径的租户解析: 实施您的租户解析逻辑.例如: 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< OpenIddictServerOptions>: public class OpenIddictServerOptionsProvider : IOptionsMonitor<OpenIddictServerOptions> { private readonly ConcurrentDictionary<(string name,string tenant),Lazy<OpenIddictServerOptions>> _cache; private readonly IOptionsFactory<OpenIddictServerOptions> _optionsFactory; private readonly TenantProvider _tenantProvider; public OpenIddictServerOptionsProvider( IOptionsFactory<OpenIddictServerOptions> optionsFactory,TenantProvider tenantProvider) { _cache = new ConcurrentDictionary<(string,string),Lazy<OpenIddictServerOptions>>(); _optionsFactory = optionsFactory; _tenantProvider = tenantProvider; } public OpenIddictServerOptions CurrentValue => Get(Options.DefaultName); public OpenIddictServerOptions Get(string name) { var tenant = _tenantProvider.GetCurrentTenant(); Lazy<OpenIddictServerOptions> Create() => new Lazy<OpenIddictServerOptions>(() => _optionsFactory.Create(name)); return _cache.GetOrAdd((name,tenant),_ => Create()).Value; } public IDisposable OnChange(Action<OpenIddictServerOptions,string> listener) => null; } 实现自定义IConfigureNamedOptions< OpenIddictServerOptions>: public class OpenIddictServerOptionsInitializer : IConfigureNamedOptions<OpenIddictServerOptions> { private readonly IDataProtectionProvider _dataProtectionProvider; private readonly TenantProvider _tenantProvider; public OpenIddictServerOptionsInitializer( IDataProtectionProvider dataProtectionProvider,TenantProvider tenantProvider) { _dataProtectionProvider = dataProtectionProvider; _tenantProvider = tenantProvider; } public void Configure(string name,OpenIddictServerOptions options) => Configure(options); public void Configure(OpenIddictServerOptions options) { var tenant = _tenantProvider.GetCurrentTenant(); // Create a tenant-specific data protection provider to ensure authorization codes,// access tokens and refresh tokens can't be read/decrypted by the other tenants. options.DataProtectionProvider = _dataProtectionProvider.CreateProtector(tenant); // Other tenant-specific options can be registered here. } } 在DI容器中注册服务: public void ConfigureServices(IServiceCollection services) { // ... // Register the OpenIddict services. services.AddOpenIddict() .AddCore(options => { // Register the Entity Framework stores. options.UseEntityFrameworkCore() .UseDbContext<ApplicationDbContext>(); }) .AddServer(options => { // Register the ASP.NET Core MVC binder used by OpenIddict. // Note: if you don't call this method,you won't be able to // bind OpenIdConnectRequest or OpenIdConnectResponse parameters. options.UseMvc(); // Note: the following options are registered globally and will be applicable // to all the tenants. They can be overridden from OpenIddictServerOptionsInitializer. options.AllowAuthorizationCodeFlow(); options.EnableAuthorizationEndpoint("/connect/authorize") .EnableTokenEndpoint("/connect/token"); options.DisableHttpsRequirement(); }); services.AddSingleton<TenantProvider>(); services.AddSingleton<IOptionsMonitor<OpenIddictServerOptions>,OpenIddictServerOptionsProvider>(); services.AddSingleton<IConfigureOptions<OpenIddictServerOptions>,OpenIddictServerOptionsInitializer>(); } 要确认这是否正常,请导航到http://localhost:[port]/fabrikam/.well-known/openid-configuration(您应该使用OpenID Connect元数据获得JSON响应). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – 具有Fluent nHibernate和Ninject的多租户.每
- asp.net – 如何让Html.RenderAction在帖子上调用Get方法?
- asp.net-mvc-4 – MVC4谷歌字体和minify
- Asp.net复选框和html数据属性
- Windows Server AppFabric分布式缓存研究
- ASP.NET MVC中是否有嵌套主页?
- asp.net-mvc – 是否有任何基于ASP.NET MVC订阅的入门工具包
- 在ASP.Net图表控件上隐藏网格线
- asp.net-mvc-4 – ClaimsAuthorizationManager.CheckAccess
- 在Asp.net mvc中应该有服务层吗?
- 要监控已部署的ASP.NET Web应用程序的关键性能指
- asp.net-mvc-3 – MVC将方法添加到jquery.valida
- asp.net-mvc-4 – 页脚的Kendo Grid Aggregation
- 用于ASP.NET的web api – 如何构建对象流
- asp.net-mvc – ASP MVC查看内容为JSON
- 在ASP.NET中接收POST数据
- ASP.NET Core集成现有系统认证
- 什么是最好的.NET库的OpenID和ASP.NET MVC?
- 实体框架 – ASP.net身份,IoC和共享DbContext
- ASP.NET MVC和Angularjs与ASP.NET MVC和Reactjs