Проверка разрешений в серверном API - PullRequest
2 голосов
/ 24 февраля 2009

наш продукт построен на архитектуре клиент-сервер, сервер реализован на Java (мы используем POJO с Spring Framework). У нас есть два уровня API на сервере:

  • внешний API , использующий веб-службы REST - полезен для внешних клиентов и интеграции с другими серверами.
  • внутренний API , который использует чистые классы Java - полезен для реального кода внутри (сколько раз бизнес-логика вызывает вызов API) и для интеграции с плагинами, разработанными внутри компании и развернутыми как части нашего продукта. Внешний REST API также использует внутренний API.

Мы реализовали проверку разрешений (используя Spring Spring) во внутреннем API, потому что хотели контролировать доступ на самом низком уровне API.

Но здесь возникает проблема : некоторые операции, определенные на уровне API, считаются запрещенными для текущего зарегистрированного пользователя, но которые должны плавно выполняться самим сервером. Например, удаление некоторого объекта может быть запрещено для пользователя, но сервер может захотеть удалить этот объект как побочный эффект какой-либо другой операции, выполняемой пользователем, и мы хотим, чтобы это было разрешено.

Итак, каков наилучший подход, позволяющий серверу выполнить операцию (в каком-то режиме суперпользователя), которая может быть запрещена для фактического вошедшего в систему пользователя?

На мой взгляд, у нас есть несколько вариантов, каждый из которых имеет свои плюсы и минусы:

  1. Реализация проверки разрешений в API внешнего уровня (REST) ​​- плохо, потому что плагины будут пропускать проверки разрешений.
  2. Отключить проверку разрешений для текущего потока после того, как запрос был удовлетворен - слишком опасно, мы можем разрешить слишком много действий сервера, которые должны быть запрещены.
  3. Явно попросить внутренний уровень API выполнить операцию в привилегированном режиме (точно так же, как PrivilegedAction в инфраструктуре безопасности Java) - слишком многословно.

Поскольку ни один из вышеперечисленных подходов не является идеальным, Интересно, каков наилучший подход к решению этой проблемы?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 25 февраля 2009

Безопасность применяется в границах модуля. Если я вас понимаю, ваша система применяет безопасность на двух уровнях абстракции (примерно) одного и того же API. Это звучит сложно, так как вы должны сделать двойную проверку безопасности на всех двух API.

Рассмотрите возможность миграции необходимых REST-методов из внутреннего API во внешний и удаления средств безопасности во внутреннем API.

  • внешний API будет управлять безопасностью для внешних клиентов (на границах вашего приложения)
  • внутренний API будет строго зарезервирован для внутреннего использования приложений и плагинов (и вы бы с радостью взломали его, поскольку к нему не привязаны никакие внешние клиенты)

Вам действительно нужно контролировать права доступа плагина к логике вашего приложения? Есть ли для этого веская причина? Плагины разрабатываются вашей компанией, в конце концов. Может быть, официальный документ, объясняющий разработчикам плагина, что не следует делать, или проверка комплекта тестов безопасности для плагина (например, плагин assert не вызывает «this» метод), тоже сделает эту работу.

Если вам все еще нужно рассматривать эти плагины как «ненадежные», добавьте методы, которые им необходимы, к внешнему API (на границе вашего приложения) и создайте определенный профиль безопасности для каждого использования: restProfile, clientProfile и pluginProfile ». Каждый из них будет иметь определенные права на ваши методы внешнего API.

1 голос
/ 25 февраля 2009

Похоже, вам нужны два уровня внутреннего API, один из которых доступен для плагинов, а другой нет.

Лучший способ включить это - использовать OSGi (или Spring Modules). Это позволяет вам явно указать, к каким пакетам и классам могут обращаться другие модули (например, модули REST и модули плагинов). Это будет уровень вашего нового внутреннего API, и вы будете использовать Spring Security для дальнейшего выборочного ограничения доступа. Внутренние пакеты и классы будут содержать методы, выполняющие все низкоуровневые операции (например, удаление сущностей), и вы не сможете вызывать их напрямую. Некоторые из представленных API просто дублируют внутренний API с проверкой безопасности, но это будет нормально.

Проблема с лучшим способом состоит в том, что Spring Modules кажутся мне все еще слишком незрелыми, чтобы их можно было использовать в новом проекте веб-приложения. Я бы ни за что не захотел вставить это в старый проект.

Вероятно, вы могли бы добиться чего-то подобного, используя Spring Security и AspectJ, но мне кажется, что снижение производительности было бы непомерно высоким.

Одним из решений, которое было бы неплохо, если бы вы могли реструктурировать свою систему, было бы отключение задач, требующих повышения безопасности, или, наоборот, их асинхронность. Используя Quartz и / или Apache Camel (или соответствующий ESB), вы можете заставить метод «удалить мою учетную запись» создать автономную задачу, которая в будущем может быть выполнена как элементарная единица работы с привилегиями администратора. Это означает, что вы можете безошибочно выполнять проверки безопасности для пользователя, запрашивающего удаление учетной записи, в совершенно отдельном потоке, где фактически происходит удаление. Это позволит сделать веб-поток более отзывчивым, хотя вы все равно захотите сделать что-то немедленно, чтобы сохранить иллюзию того, что запрошенное действие было выполнено.

0 голосов
/ 24 февраля 2009

Если вы используете Spring, вы также можете использовать его полностью. Spring предлагает AOP , который позволяет использовать перехватчики и выполнять эти межсистемные проверки, а в случае неавторизованного действия предотвращать это действие.

Подробнее об этом можно прочитать в онлайн-документации Spring здесь .

Надеюсь, это поможет ...

Ювал = 8 -)

...