【问题标题】:How do you identify the tenant using a JWT when integrating with Autofac?在与 Autofac 集成时如何使用 JWT 识别租户?
【发布时间】:2018-09-05 06:44:35
【问题描述】:

我正在尝试构建多租户 ASP.NET Core 2.1 WebApi。 我想从 jwt 令牌而不是从 url 或端口中选择租户。 所以当用户请求令牌时,我将它的tenant_id 放入令牌中。 但是当我尝试像这样解析 Autofac 多租户策略 (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;
    }

我看到 context.User 没有被 jet 填充,那是因为 Jwt 身份验证没有发生 jet。

怎么做?

【问题讨论】:

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


    【解决方案1】:

    简短的版本是你不能免费这样做。这通常是为什么最好使用你可以信任但不需要额外支持的东西(比如请求中的主机名)。

    如果您只能信任令牌,那么我已经看到大致这样做的解决方案(在伪代码中看起来像 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() 方法中手动调用令牌验证逻辑,并确保它在继续之前有效。这有点痛苦,但并非不可能。这意味着从技术上讲,您将在任何给定请求期间运行两次,而且这有点昂贵,因此如果您走这条路线并平衡安全隐患,请考虑性能。

    【讨论】:

    • 感谢@Travis 的详尽解释。我想我可以以某种方式将令牌身份验证移到管道上方,因此它发生在 Autofac 租户识别之前。我想要这个的唯一原因是每个租户的数据库连接字符串,所以我可以为每个租户实例化一个不同的数据库。
    猜你喜欢
    • 2020-06-23
    • 2016-11-15
    • 2019-12-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    相关资源
    最近更新 更多