Как вы определяете арендатора с помощью JWT при интеграции с Autofac? - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь создать мультитенантный ASP.NET Core 2.1 WebApi. Я хотел бы выбрать арендатора из токена JWT, а не из URL или порта. Поэтому, когда пользователь запрашивает токен, я помещаю его tenant_id в токен. Но когда я пытаюсь разрешить TenantId в стратегии многопользовательского Autofac (ITenantIdentificationStrategy) следующим образом:

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 не заполняется струями, и это потому, что аутентификация Jwt не происходит в струе.

Как это сделать?

1 Ответ

0 голосов
/ 05 сентября 2018

Короткая версия этого , вы не можете сделать это бесплатно. В общем, поэтому лучше использовать то, чему вы можете доверять, но не требует дополнительной поддержки (например, имя хоста в запросе).

Если вы можете доверять только токену, то я видел решения, которые примерно делают это (в псевдокоде, который выглядит как 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() и убедиться, что она действительна, прежде чем продолжить. Это больно, но не невозможно. Технически это означало бы, что вы выполняете это дважды во время любого данного запроса, и это довольно дорого, поэтому подумайте о производительности, если вы пойдете по этому пути, и сопоставьте это с последствиями для безопасности.

...