Стратегия авторизации для каждого клиента

У меня есть приложение Rails 4. Я использую devise для аутентификации и opro для предоставления oauth2 с моим API. Все запросы авторизуются с помощью политик pundit, и до сих пор эта настройка работала нормально.

В настоящее время моя авторизация всегда выполняется для каждого пользователя. Это имеет смысл, так как обычно каждый запрос выполняется от имени конкретного пользователя, который либо аутентифицируется в сеансе, либо предоставляет токен oauth.

Новая проблема заключается в следующем: у меня есть определенные потребители API (далее я буду называть их устройствами), чьи запросы нельзя рассматривать как запросы от конкретного пользователя. Одним из них является сервер Asterisk, который может обмениваться информацией с API, другой — блок GPS-трекинга, который постоянно отправляет точки отслеживания в API.

Таким образом, мне нужно авторизовать определенные операции API для каждого устройства, то есть не обязательно current_user доступно. Однако отсутствие current_user портит мою концепцию авторизации.

Я уже рассмотрел несколько подходов к проблеме:

  • creating dedicated users for each device and authorizing them to do the specific action
    • pro: does not screw up my authorization scheme
    • против: это означало бы переосмыслить User-модель, поскольку в настоящее время у меня есть только «естественные пользователи», которым требуется имя, день рождения, адрес электронной почты и т. д.
  • creating dedicated controllers with adapted authorization scheme
    • pro: high flexibility
    • contra:
      • authentication for devices required
      • требуются дополнительные конечные точки API, не очень СУХОЙ

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


person Peter Sorowka    schedule 02.07.2014    source источник


Ответы (1)


Вам нужен отдельный слой, который выполняет проверку авторизации, а также глобальные атрибуты с именами caller_id и caller_type (это просто примеры).

Затем вы хотите реализовать логику, например:

  • if caller_type == device and caller_id == ... then
  • if caller_type == user and caller_id == ... then

Для этого вы можете просто написать свой собственный маленький класс. В качестве альтернативы вы можете использовать XACML для определения логики авторизации. См. этот запись в блоге, которая применяет XACML к сервлетам. Тот же принцип можно применить к вашему приложению Rails.

ХТХ, Дэвид.

person David Brossard    schedule 04.07.2014
comment
спасибо за ваши предложения, но позвольте мне спросить несколько деталей. Я рассматривал XACML некоторое время назад, но чувствовал, что пока нет хорошей реализации на рельсах. Поэтому я реализовал авторизацию с помощью драгоценного камня Pundit, и это отлично работает. Что касается упомянутого вами «отдельного слоя», вы имеете в виду что-то вроде полиморфной пользовательской модели, например. иметь общую модель User и более конкретные NaturalUser и DeviceUser, а затем авторизоваться в общем базовом классе? Или вы предлагаете добавить промежуточное ПО? - person Peter Sorowka; 04.07.2014
comment
Что касается отдельного уровня, я имел в виду отделение кода авторизации от бизнес-логики. ЕСЛИ вы используете драгоценный камень пандита, то вы уже делаете это. Использование общего класса User, который затем расширяется, имеет большой смысл IMHO. Я не знаю ни о какой реализации RoR XACML, но это не имеет значения, если у вас есть средства для вызова механизма XACML из Ruby, верно? Axiomatics — поставщик, на которого я работаю, — предоставляет API, так что вы можете вызывать механизм XACML из нескольких языков, включая Ruby. - person David Brossard; 08.07.2014