与Autofac集成时,如何使用JWT识别租户?

时间:2018-09-04 14:04:31

标签: jwt autofac multi-tenant asp.net-core-webapi

我正在尝试构建多租户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。

如何做到?

1 个答案:

答案 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()方法中手动调用令牌验证逻辑,并在继续操作之前确保其有效。这有点痛苦,但并非不可能。从技术上讲,这意味着您将在任何给定请求中运行两次,这是很昂贵的,因此,如果您走那条路线并在安全性和安全性之间取得平衡,请考虑性能。