WebApi 2 - авторизация в нескольких одновременных контекстах, управление состоянием REST - PullRequest
0 голосов
/ 30 мая 2018

У меня есть конечная точка Web Api 2, которую я пытаюсь защитить с помощью специального атрибута Authorize.Внутри этого атрибута я проверяю, есть ли у пользователя необходимые роли, такие как:

            if (!user.HasRoleInInstitution(institutionId, Role.SomeRole))
            {
                filterContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
                return;
            }

Проблема, с которой я сталкиваюсь - это идентификатор института.Конечная точка должна быть доступна в контексте учреждения, в котором каждый пользователь может иметь разные роли в разных учреждениях, поэтому проверка должна проверять, есть ли у пользователя роли в данном учреждении, к которому обращается пользователь.

Я мог бы сохранить доступный в данный моментinstituId в Session, например:

var session = HttpContext.Current.Session;

Это, однако:

A) Против принципов REST, поскольку конечная точка не должна иметь состояния

B) Доступ к сеансам обычно занимает много времени, поэтомуэто приводит к снижению производительности в недопустимых сценариях, таких как Авторизация.

Я мог бы также передавать идентификатор института от клиента при каждом запросе, а затем использовать RouteData для извлечения его в атрибуте, например:

var institutionId = filterContext.ControllerContext.RouteData["institutionId"]; 

Проблема с этим подходом заключается в следующем:

A) Если другой разработчик использует «someInstitutionId» вместо «instituId» в качестве параметра маршрута, тогда эта проверка прекратит

B) Передача институтаId вкаждый запрос - ужасная трата пропускной способности

Finally Я мог бы просто добавить в текущий момент доступную учетную запись для учреждения или передать файлы cookie, но это вынуждает пользователя перезаписываться каждый раз, когда он хочет использовать другое учреждение, и он не может открыть несколько экземпляров приложения для разных учреждений, что является жестким требованием..

Каков наилучший подход для подобных сценариев?

1 Ответ

0 голосов
/ 02 ноября 2018

Так что вы не хотите использовать Session, потому что он против REST (и это здорово!), Но вы не хотите, чтобы клиентское приложение отправляло вам идентификатор института внутри запроса ... Это проблема логики.Я имею в виду, просто подумайте об этом.

Как клиентское приложение может предоставить вам информацию, если она не находится внутри запроса, потому что вы не используете Session?Это должно быть внутри каждого запроса.И это не «ужасная трата Bandwitch», ваш идентификатор института не является информацией 2Go, так что ...

Просто используйте JWT, храните идентификатор института внутри, как каждый раз, когда клиент будет пытаться получить доступ к методуВнутри вашего контроллера атрибут Authorize проверит, получил ли он доступ, и он будет работать очень хорошо, даже если у него было несколько экземпляров приложения, потому что идентификатор института будет предоставлен JWT по КАЖДОМУ запросу!:)

И если вы не хотите, чтобы пользователь входил в систему каждый раз, когда он открывает приложение в другом учреждении, просто заставьте клиентское приложение записать идентификатор института внутри токена.Таким образом, он входит в систему с помощью ClientApp1, и вы даете ему токен без instituId, но когда ClientApp1 выполняет вызов, он записывает в токене instituId, например, вы можете проверить доступ, и если клиент открывает ClientApp2, вы автоматически предоставляете токен, который вы предоставляетеClientApp1 (т. Е. Тот, у которого нет идентификатор института) и ClientApp2 будут перезаписывать идентификатор института и отправлять вам идентификатор института, связанный с ClientApp2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...