目前,我第一次尝试一种微服务体系结构,并希望将构建在此体系结构上的多租户应用程序组合在一起。租户是用自己的子域创建的,租户所有者可以创建更多链接到该租户的用户帐户。
目前,我已经设置了identity api,并正在考虑编写其他内容,如下所示:

网关将作为前端后端实现,并根据需要将数据聚合到该网关以满足客户端请求。
在identity API中,我使用SaasKit中间件检查子域并获取租户详细信息。我想知道在其他服务中应用这个租户发现的最佳方法是什么?我对创建一种可能破坏微服务自主性的耦合非常谨慎。当向服务提出请求时,我会在网关中进行租户发现并将租户ID传递给微服务吗?我应该在每个服务中保存租户信息的本地副本吗?还是应该在每个服务中使用SaasKit并调用每个服务中的identity API来获取租户信息(如果还没有缓存)?
编辑:为如何创建租户添加一些上下文;租户是通过来自独立系统的API调用创建的,该系统提供了一个由独立于此的中央身份验证服务创建的JWT。用户也是这样创建的,但是这里创建的用户是在这里进行身份验证的,而不是“其他”身份验证服务。
发布于 2020-10-16 14:00:19
我使用的实现完全依赖于SaaS工具包,用于身份服务使用检测到的域对正确的租户进行身份验证。当我将JWT传递到网关,然后转到底层服务时,将包含一个用于承租者ID的tid字段。
然后,我在实体框架上下文中使用了该方法。例如:
public class MyDbContext : DbContext
{
private readonly ITenantProvider _tenantProvider;
private Guid? TenantId => _tenantProvider.GetTenantId();
public MyDbContext(DbContextOptions<MyDbContext> options, ITenantProvider tenantProvider) : base(options)
{
_tenantProvider = tenantProvider;
}
public DbSet<MyModel> MyModels { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<MyModel>().HasQueryFilter(s => TenantId != null && s.TenantId == TenantId);
}
}并像这样由ITenantProvider实现。我同时检查了tid和tenantid的url,因为如果您添加了tid属性,那么JWT的默认用法是使用这里,如所描述的:
public class HttpContextTenantProvider : ITenantProvider
{
private readonly HttpContext _httpContext;
public HttpContextTenantProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContext = httpContextAccessor.HttpContext;
}
public Guid? GetTenantId()
{
if (_httpContext?.User == null)
{
return null;
}
var tenantIdClaim = _httpContext.User.Claims.FirstOrDefault(c => c.Type.Equals("http://schemas.microsoft.com/identity/claims/tenantid", StringComparison.InvariantCultureIgnoreCase) || c.Type.Equals("tid", StringComparison.InvariantCultureIgnoreCase));
if (tenantIdClaim == null)
{
return null;
}
return Guid.Parse(tenantIdClaim.Value);
}
}发布于 2019-07-23 09:44:22
由于您使用的是微服务,我猜您使用的是基于令牌的身份验证/授权,这意味着您有一个签名令牌,您可以在其中安全地将数据从一个客户端传递到一个服务,并从一个服务到另一个服务来授权请求。如果没有,我建议这样做,因为这将使你能够:
https://softwareengineering.stackexchange.com/questions/395071
复制相似问题