我正在尝试构建多租户ASP.NET Core 2.1 WebApi。 我想从jwt令牌而不是从url或端口中选择租户。 因此,当用户请求令牌时,我将其tenant_id放入令牌中。 但是,当我尝试像这样在Autofac Multitenant策略(ITenantIdentificationStrategy)中解析TenantId时:
public bool TryIdentifyTenant(out object tenantId)
{
_logger.LogInformation("***********************************TryIdentify");
tenantId = null;
try
{
var context = _httpContextAccessor()?.HttpContext;
if(context != null && context.Request != null)
{
var id = context.User.FindFirst("tenantId")?.Value;
if (id != null)
{
tenantId = id;
}
}
}
catch(Exception)
{
// Happens at app startup in IIS 7.0
}
return tenantId != null;
}
我看到上下文。用户不是jet填充的,这是因为Jwt身份验证没有发生jet。
如何做到?
答案 0 :(得分:0)
它的简短版本是您不能免费做到这一点。通常这就是为什么最好使用您可以信任但不需要其他支持(例如请求中的主机名)。
如果您只能信任令牌,那么我看到的解决方案大致 可以做到这一点(在伪代码中,看起来像C#):
if(context.Items["tenant"] == null && context.User == null)
{
// no tenant has been identified before and
// token validation hasn't happened so manually
// get the tenant from the token knowing you are
// potentially getting an untrusted value.
context.Items["tenant"] = ManuallyLookAtToken();
}
else if(context.Items["tenant_trusted"] == null && context.User != null)
{
// a "trusted" tenant ID hasn't been read from the user
// principal so let's update.
context.Items["tenant"] = GetTenantFrom(context.User);
context.Items["tenant_trusted"] = true;
}
return context.Items["tenant"];
进行此类操作的风险在于,您容易受到攻击,即有人发送格式错误的令牌,该令牌的寿命只能长到可以超过请求管道的初始部分。令牌不会通过验证,因此常规的安全性应予以注意,但是在此之前,承租人的价值未得到官方验证。如果您有管道逻辑,例如,……在首次请求时自动提供新租户或类似的东西?……那么您可能会遇到麻烦。有人可能会随机生成数百万个租户名称并杀死您的数据库。在这种情况下,有时您可能会回退到其他名称,例如主机名。
或者,您实际上可以在该ManuallyLookAtToken()
方法中手动调用令牌验证逻辑,并在继续操作之前确保其有效。这有点痛苦,但并非不可能。从技术上讲,这意味着您将在任何给定请求中运行两次,这是很昂贵的,因此,如果您走那条路线并在安全性和安全性之间取得平衡,请考虑性能。