JAAS & JACC: Как я могу выгнать пользователя?

В настоящее время мы внедряем JAAS и JACC, используя JBoss EAP 6.4/7.0. Просто краткое объяснение того, как мы применяем вещи:

  • мы используем HttpServletRequest.login(...) аутентифицировать
  • впоследствии мы используем HttpServletRequest.logout() выйти из системы
  • у нас есть LoginModule, который проверяет учетные данные и подготавливает роли.

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

  • отменить чужую роль для входа в систему и
  • выгнать их из любых в настоящее время активных сессий.

Первая часть проста, но я с трудом пытаюсь понять, как я могу сделать чей-то сеанс недействительным. Есть ли способ, которым я мог бы как-то завладеть предметом / сеансом другого пользователя и сделать его недействительным?

Очень признателен

1 ответ

Примечание по терминологии:

  • Механизм аутентификации (AM) в данном документе относится к любому компоненту, ответственному за создание аутентификационных утверждений, относящихся к, и регистрацию / установление, в результате, идентичности аутентифицированных объектов вызывающего абонента с / во время выполнения Java EE. Такие компоненты могут быть специфическими для сервера приложений (AS) или стандарта Java EE; Детали или типы реализации AS, предназначенные для расширения разработчиком приложения Java EE; развернут как часть приложения Java EE или как часть AS. Одним из таких компонентов является ваш JAAS LoginModule (LM). Хотя Identity Store (IS), по-видимому, является (полу) нормативным термином, используемым для обозначения (среди прочего) LM в настоящее время, я хотел зарезервировать его для уровня персистентности, специфичного для приложения (например, JPA). @Entity ) типы, представляющие ваших пользователей, и, следовательно, должны были установить это (плохо определенное) различие. "Почему вы расплывчаты?", Вы можете спросить: "Разве вы не можете просто назвать LM LM?". Потому что я ничего не знаю о JBoss LM! На самом деле, я не являюсь пользователем JBoss и не использую JAAS в Java EE. Тем не менее, я чувствовал, что мог бы дать ответ, относящийся к общему делу, отсюда неизбежная неопределенность.
  • Деактивированный пользователь относится к отсутствию лучшего термина к вашему "выгоняемому пользователю", то есть к пользователю, чьи права (группы, роли, разрешения - что бы там ни называли) были отозваны в каким-то образом на уровне IS.


Прежде всего, не существует стандартного API Java EE, который бы Subject или же HttpSession произвольного пользователя в ваш код. Вы можете теоретически записать эту информацию самостоятельно, например, во время аутентификации, но я предполагаю, что это не совсем то, что вы хотите. Кроме того, относительно Subject в частности, хотя ни один стандарт явно не запрещает его (Principal изменения / сбора учетных данных) при обслуживании запроса на Subject от имени, никто не заявляет, что это должно быть либо. На самом деле даже не ясно, является ли текущий аутентифицированный вызывающий абонент Subject - тот, который заполняется во время аутентификации и может быть получен через JACC "javax.security.auth.Subject.container"PolicyContextHandler - должен совпадать со структурой данных, которую среда выполнения запрашивает Policy с при принятии разрешительных решений; то есть среда выполнения может только предоставить вам копию, использовать совершенно другое представление аутентифицированного вызывающего абонента внутри или что-то среднее между ними. Поэтому, даже если вы смогли изменить Subject это не обязательно повлияет на действующий контекст безопасности.

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

Запрет повторной аутентификации звонящего

После того как приложение деактивировало пользователя, оно должно как-то дать AM команду прекратить повторную аутентификацию при последующих запросах, которые он выдает. Чтобы уменьшить связь, приложение обычно не связывается напрямую с AM, но вместо этого удовлетворяет некоторому условию, оцененному более поздним. Например, приложение может назначить пользователю какое-то специальное право "locked_out" или установить HttpSession приписывать. Когда его попросят повторно подтвердить подлинность деактивированного пользователя, AM подтвердит деактивацию и откажется повторно подтвердить его подлинность. Впоследствии это сделает недействительным сеанс пользователя. Как именно это будет достигнуто, зависит от его вида и реализации. Ваш LM, вероятно, придется использовать "javax.servlet.http.HttpServletRequest" JACC PolicyContextHandler для этой цели. Яшма ServerAuthModule будет иметь немедленный доступ к экземпляру запроса, получив его как validateRequest аргумент. Некоторому другому компоненту, возможно, придется прибегнуть к использованию внутренних компонентов AS или обременять приложение ответственностью за недействительность сеанса (некоторый компонент, перехватывающий вызов, такой как сервлет). Filter, придется запросить IS во второй раз и действовать соответственно).

Вышеупомянутый подход, очевидно, требует способности изменять функциональность AM. Кроме того, AM кэширования должен оценить упомянутое условие деактивации, прежде чем повторно использовать свой ранее установленный результат аутентификации. И наконец, как упоминалось в комментарии, если во время отзыва доступа к ИС пользователя выполняется запрос от имени этого пользователя (поступивший / прошедший проверку подлинности до наступления события отзыва доступа) обслуживание этого запроса будет завершено нормально (если приложение не запрашивает повторную аутентификацию этого пользователя, например, через HttpServletRequest# (login | authenticate).

Запрет повторной авторизации звонящего

Хотя, как я уже упоминал в начале, пользователи Subject s не легко получить / изменить, поддержка Policy В отличие от этого, в JACC-совместимых средах выполнения Java EE те, кто авторизован, на самом деле. К сожалению, поставщик JACC, предоставленный по умолчанию AS (PolicyConfiguration + Policy) имеет серьезное ограничение: он позволяет работать только с ролями Java EE, а не с вызывающим Principal s сопоставлены, т. е. "имея", эти роли. Например, поставщик по умолчанию позволяет расширить Permission с этим Principal s сопоставлены с ролью администратора; это позволяет вам удалить роль "администратора" вместе со всеми его Permission s; но это не позволяет вам решать, кто станет "администратором" - по крайней мере, не стандартным способом.

Это ограничение в основном оставляет вам две альтернативы, поскольку JACC обеспокоен: либо попросите АМ добавить группу-пустышку Principal каждому звонящему Subject с тем же именем, что и у соответствующего абонента Principal, Затем, после деактивации пользователя, добавьте (через PolicyConfiguration#addToRole) Кастон Permission относящиеся к группе "пустышка". Наконец, проверьте (например, через AccessController # checkPermission) из кода "application-space", есть ли у пользователя Permission и если так, выгнать их. Но подождите, это совершенно бессмысленно - зачем вообще использовать Policy во-первых, если он не способен самостоятельно обрабатывать авторизацию? Альтернативой является создание и установка собственного провайдера JACC. Это даст вам полный контроль над Principal - / сопоставления между группами и позволяют вам действовать практически так, как вам угодно, с точки зрения авторизации, с этой информацией с этого момента. Однако написание нового провайдера нетривиально, особенно потому, что оно должно соответствовать потребностям авторизации во всей JRE, а не только в рамках одного приложения. Я сомневаюсь, что ваше требование оправдывает такой объем работы. Если вы все еще хотите пойти по этому пути, статьи, связанные с JACC в блоге Арджана Тиймса, станут отличной отправной точкой.

Другие вопросы по тегам