Apache Tomcat 1.7 Как передать дополнительные параметры в JAAS

Согласно документации Apache Tomcat 1.7:

Напишите свои собственные классы LoginModule, User и Role на основе JAAS (см. Учебное пособие по аутентификации JAAS и Руководство разработчика модуля входа в JAAS) для управления контекстом входа в систему JAAS (javax.security.auth.login.LoginContext). При разработке модуля LoginModule, обратите внимание, что встроенный в JAASRealm CallbackHandler в настоящее время распознает только NameCallback и PasswordCallback.

Он поддерживает только NameCallback и PasswordCallback. Я хочу передать дополнительные параметры модулю входа в JAAS, но не могу из-за этого ограничения.

Как передать дополнительные параметры модулю входа в JAAS?


person yapkm01    schedule 09.08.2015    source источник
comment
Вы определяете их в файле jaas.config вместе с модулями входа в систему и извлекаете их во время инициализации.   -  person user207421    schedule 09.08.2015
comment
@EJP Я использую по умолчанию tomcat org.apache.catalina.realm.JAASRealm, который я определил в context.xml. Этот JAASRealm по умолчанию вызывает собственный обработчик обратного вызова. Несмотря на то, что у меня определен пользовательский обработчик обратного вызова, он не будет вызван JAASRealm. Как заставить этот JAASRealm, определенный в моем context.xml, использовать этот пользовательский обработчик обратного вызова?   -  person yapkm01    schedule 09.08.2015
comment
Tomcat 1.7, конечно? Или, скорее, Tomcat 7, о чем свидетельствуют использованные вами теги?   -  person f_puras    schedule 09.08.2015
comment
Кажется, вы здесь запутались. Область JAAS вызывает модули входа, а они вызывают обработчики. Вам нужно будет написать свой собственный модуль входа в систему для вызова обработчика.   -  person user207421    schedule 09.08.2015
comment
@EJP Думаю, вы меня неправильно поняли. Tomcat JAASRealm (org.apache.catalina.realm.JAASRealm) не требует создания LoginContext. К вашему сведению, LoginContext позволяет использовать собственный обработчик обратного вызова. Поскольку Tomcat JAASRealm этого не требует, значит, он использует собственный обработчик обратного вызова. Это проблема, с которой я столкнулся сейчас   -  person yapkm01    schedule 10.08.2015
comment
@EJP какое здесь решение?   -  person yapkm01    schedule 11.08.2015
comment
Зачем нужны эти параметры?   -  person Michael-O    schedule 12.08.2015
comment
@ Michael-O Пользователь abc зарегистрирован как клиент в LDAP (например, cn = abc, groupofnames = customer). Пользователь abc и заказчик параметра, отправленные в JAAS, будут успешно аутентифицироваться, но если отправляемый подрядчик параметров, аутентификация должна завершиться неудачно, поскольку в LDAP нет пользователя abc в группе groupofnames = contractor. Этот третий параметр необходимо передать вместе с идентификатором пользователя и паролем в модуль входа в JAAS, иначе как LDAP узнает, должен ли запрос искать groupofnames = клиенты или подрядчики для этого пользователя   -  person yapkm01    schedule 12.08.2015
comment
@ yapkm01 Вам следует переосмыслить структуру каталогов. В нашей AD ›500 000 учетных записей и достаточно принципала + пароль.   -  person Michael-O    schedule 13.08.2015
comment
@ Майкл-О, я не думаю, что ты полностью понимаешь, в чем моя проблема. В любом случае, спасибо   -  person yapkm01    schedule 15.08.2015
comment
@ yapkm01 Удалось разобраться? У меня аналогичная проблема с JAASRealms.   -  person Setup    schedule 13.04.2016


Ответы (3)


Напишите свой собственный CallbackHandler. Подробнее см. http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/tutorials/GeneralAcnOnly.html.

Например, MyCallbackHandler может поддерживать дополнительный TextOutputCallback

public void handle(Callback[] callbacks)
  throws IOException, UnsupportedCallbackException {

  for (int i = 0; i < callbacks.length; i++) {
    if (callbacks[i] instanceof TextOutputCallback) {

      // display a message according to a specified type
      . . .

    } else if (callbacks[i] instanceof NameCallback) {

      // prompt the user for a username
      . . .

    } else if (callbacks[i] instanceof PasswordCallback) {

      // prompt the user for a password
      . . .

    } else {
        throw new UnsupportedCallbackException
         (callbacks[i], "Unrecognized Callback");
    }
  }
}
person Alin Pandichi    schedule 09.08.2015
comment
Я сделал именно это, но по умолчанию org.apache.catalina.realm.JAASRealm, определенный в context.xml, этого не вызывает. Он вызывает другой обработчик обратного вызова. Как заставить этот JAASRealm вызывать мой собственный обработчик обратного вызова? - person yapkm01; 09.08.2015
comment
Глядя на исходный код org.apache.catalina.realm.JAASRealm, я вижу, что он всегда использует new JAASCallbackHandler () для передачи обработчика обратного вызова. Я начинаю думать, что установить собственный с помощью Tomcat JAAS невозможно. В автономных приложениях вы должны создать LoginContext с помощью вашего обработчика: loginContext = new LoginContext (Sample, new MyCallbackHandler ()); - person Alin Pandichi; 09.08.2015
comment
Итак, какое здесь решение? - person yapkm01; 11.08.2015
comment
Вернемся на шаг назад и спросим: зачем вам дополнительный параметр? Какая вам от этого польза? - person Alin Pandichi; 12.08.2015
comment
Я создаю сайт домашнего консультанта, где клиент может войти в систему и запросить услугу у подрядчика. Подрядчик также может войти в систему, чтобы зарегистрироваться в качестве профессионального подрядчика. Фактическая аутентификация находится в модуле входа в JAAS. Это имя пользователя будет проверено с использованием аутентификации LDAP. Однако для аутентификации LDAP необходимо знать, является ли это имя пользователя заказчиком или подрядчиком. Имя пользователя клиента, например abcdef должен успешно войти в систему в качестве клиента, но не должен работать, если он используется в качестве имени пользователя подрядчика. Для JAAS необходим дополнительный параметр с указанием заказчика или подрядчика. - person yapkm01; 12.08.2015
comment
Если вы выполняете аутентификацию по LDAP, не лучше ли подойдет JNDIRealm? Или com.sun.security.auth.module.LdapLoginModule? - person Alin Pandichi; 12.08.2015
comment
Модуль входа в систему JAAS является рекомендуемым выбором для аутентификации. Он используется для передачи учетных данных в LDAP для аутентификации. - person yapkm01; 12.08.2015
comment
На данный момент я вижу два других способа: 1. Придумать другой способ определить, является ли пользователь заказчиком или подрядчиком, исключительно на основе имени пользователя (эта информация может храниться где-нибудь в вашей базе данных, если это еще не сделано). Таким образом, вам не понадобится третий параметр обратного вызова. 2. Или вы можете сами написать собственное Realm, которое выполняет аналогичную работу, как JAASRealm (возможно, расширяет его, если возможно). Затем эта настраиваемая область может использовать ваш настраиваемый MyCallbackHandler. Хотя этот вариант кажется немного экстремальным ... - person Alin Pandichi; 12.08.2015
comment
Проблема здесь в том, что существует четкое разделение между модулем JAAS и уровнем контейнера, где находится большая часть информации уровня запроса / сервлета / контекста. Я не хочу тратить время на написание пользовательского Realm, поскольку это отвлечет меня от моей реальной деловой работы. Я не вижу других быстрых решений, кроме предложенного sibnick - person yapkm01; 12.08.2015
comment
Мне еще нужен третий параметр. Пожалуйста, посмотрите мои комментарии, на которые я ответил Michael-O - person yapkm01; 12.08.2015

Обычный способ подойти к этому - сопоставить ваши contractor и customer группы с ролями.

  • Загрузите копию спецификации сервлета 3.0 (Tomcat 7.0 является ее реализацией) и прочтите главу о безопасности, чтобы увидеть множество опций, которые предоставляет контейнер сервлетов для аутентификации пользователей на основе имени пользователя и пароля, а затем авторизации пользователей на основе их роль.
  • Следуйте инструкциям в документации Tomcat для настройки JNDIRealm . Это дает возможность настроить Tomcat для использования сервера LDAP для аутентификации (имя пользователя / пароль) и авторизации (проверка ролей).

Использование подобного подхода, основанного на спецификациях, дает дополнительное преимущество в обеспечении переносимости вашего решения, если вы решите в будущем перейти на полномасштабное решение Java EE (например, JBossAS / WildFly, Glassfish, WebSphere и т. Д.).

Кроме того, если вы сможете перейти на Tomcat 8, у вас будет доступ к дополнительным функциям аутентификации, которые были добавлены в спецификацию сервлета 3.1.

person Steve C    schedule 17.08.2015
comment
Что произойдет, если у пользователя несколько ролей? На экране входа в систему с использованием только имени пользователя и пароля, какую роль будет выполнять этот человек при входе в систему? Имейте в виду, что разные роли могут предоставлять разный авторизационный доступ к разным страницам. - person yapkm01; 19.08.2015
comment
Это решение допускает несколько ролей. Как это сделать - решать вам. Что должно произойти, если пользователь одновременно является contractor и customer? - person Steve C; 19.08.2015
comment
Ага. Скажем, пользователь abc одновременно является подрядчиком и заказчиком. Каждая роль имеет свои права доступа к определенным экранам. На экране входа в систему abc войдите, просто используя его идентификатор и пароль. Какие роли знает сервер? Сторона сервера никак не узнает. Решение: вам нужен экран входа в систему с другим полем, информирующим о том, что пользователь сервера abc теперь входит в систему как подрядчик (в качестве примера). Затем сервер знает, как назначить роль подрядчика abc и предоставить ему доступ к экранам, связанным с подрядчиком (а не с клиентами). Видите картинку сейчас? - person yapkm01; 20.08.2015
comment
Нет. Все дело в том, что сервер знает. Например, в любое время в сервлете вы можете протестировать: if (httpServletRequest.isUserInRole("contractor")) { ... } - person Steve C; 20.08.2015
comment
Я понимаю модель безопасности javaee. Вернемся к основам. Этот пользователь abc имеет роль заказчика и подрядчика, определенную в LDAP. На экране входа в систему пользователь abc входит в систему, используя abc / пароль. Какую роль JAAS должен назначить этому новому входу в систему abc? Ваш оператор isUserInRole выполняется только после того, как роль была назначена и использована для авторизации на разных ресурсах. - person yapkm01; 22.08.2015
comment
У пользователя может быть любое количество ролей. После аутентификации они считаются выполняющими все роли, которым они были назначены. - person Steve C; 22.08.2015

Самый простой способ: объединить все параметры в одну строку и разделить ее позже

person sibnick    schedule 09.08.2015
comment
да. Я подумал об этом, хотя на самом деле он не очень хороший. Другого решения не вижу. Так удивительно, что Tomcat не может решить такую ​​простую проблему. - person yapkm01; 11.08.2015