Обработка ошибок аутентификации Java EE

В настоящее время мы пытаемся реализовать веб-приложение, использующее механизм аутентификации Java EE с логином на основе FORM, внутри веб-контейнера Websphere 6.1. Если аутентификация прошла успешно, у нас все работает; извлекаются группы членства LDAP, выполняется сопоставление групп с ролями, а роли возвращаются и правильно интерпретируются веб-приложением.

Если аутентификация не удалась, возвращается страница с ошибкой входа в систему. Однако это статическая страница, на которой просто написано что-то вроде «произошла ошибка». Как нам отловить конкретную ошибку, которая помешала успешному входу в систему (неверное имя пользователя / пароль, недоступен репозиторий LDAP, учетная запись заблокирована, срок действия пароля истек и т. д.)? Похоже, что должен быть какой-то простой способ сделать это, так как вы хотели бы обрабатывать некоторые исключения «безопасности» иначе, чем другие.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
5 906
4

Ответы 4

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

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

Проверьте эту статью Защита приложений J2EE с помощью фильтра сервлетов. Я считаю, что это покрывает ваше требование, чтобы указать причину ошибки аутентификации.

Хорошая статья, но я прочитал вопрос «как мне сообщить об ошибках во время аутентификации пользователю». Аутентификация (в JEE) отделена от приложения, поэтому фильтры не могут перехватить запрос (и имя пользователя / пароль), используемый для входа в систему. Обычно это хорошо, за исключением таких ситуаций ...

Olaf Kock 24.01.2009 10:05

Я использую Struts, поэтому он будет выполнять пересылку за вас. Если у вас нет фреймворка (почему бы и нет?), Вам придется делать это вручную.

Спецификация Java EE охватывает сервлет j_security_check.

Страница входа отправляет сообщения j_username и j_password сервлету j_security_check. Ваше приложение будет настроено на ошибку для неавторизованной страницы (см. Web.xml), но (изначально) будет вызывать сервлет. 401 или 403 перейдут на запрещенную страницу (снова web.xml)

Внутри этого сервлета (который расширяет HttpServlet) вы проверите все эти хорошие вещи.

public final void doGet(javax.servlet.http.HttpServletRequest request,
    javax.servlet.http.HttpServletResponse response)
    throws javax.servlet.ServletException, java.io.IOException
{
    // initialize the app
    AppInit initializer = new AppInit();

    // get the logger
    log = new Log4jWrapper(this.getClass());

    // initialize the application session
    HttpSession sess = request.getSession(true);
    sess.setAttribute(CommonConstants.SESSION_CURR_USER_ID, request.getRemoteUser());

    // initialize the JSP to forward to based on the user role
    String fwdJSP = "SetupMainPage.jsp";
    if (request.isUserInRole(CommonConstants.ROLE_MANAGER)) {
        log.debug("User is a Manager");
    }
    //else other role checks - (these are users in groups in the LDAP)
    // initialize the application session and set a variable to indicate that
    // we are coming from a first time login (not a timeout login)
    sess.setAttribute(CommonConstants.SESSION_COMING_FROM_INITIAL_LOGIN,"TRUE");
    disp = getServletContext().getRequestDispatcher("SetupMainPage.jsp");
    disp.forward(request, response);
}
//else failure

Неизвестный пользователь

[11/22/08 8:54:47:993 EST] 7f6ac69c FormLoginServ E SECJ0118E: Authentication error during authentication for user s

правильный пользователь - неправильный пароль, но request.getRemoteUser () будет иметь значение

[11/22/08 8:56:45:082 EST] 7f51469c FormLoginServ E SECJ0118E: Authentication error during authentication for user jbsymolo

К сожалению, у меня нет примеров того, что кто-то заблокирован, но я предполагаю, что в главном каталоге безопасности (LDAP) у вас будет запись для пользователя для этого.

Это от кого-то другого (поэтому я не могу поверить в это)

I think this page describes how to do what you want to do.

Specifically how to retrieve the authentication exception from an arbitrary underlying authentication source (looks like Websphere calls them user registries).

Throwable t = com.ibm.websphere.security.auth.WSSubject.getRootLoginException();
if (t != null)
t = determineCause(t);

Where determineCause() is defined on the same page. This way, even if your server is configured to authenticate against a John Deer tractor, you will have access to the "OutOfGasLoginException" if there is one. The above code can go into the Servlet, Servlet Filter, or JSP that is redirect to by the container (as described above by jsymolon). It simply examines the exceptions and then places a corresponding friendly error message on the resulting page.

Интересно - я никогда не пробовал реализовать свой собственный сервлет j_security_check. Я всегда предполагал, что контейнер позаботится об этом, и приложение не сможет увидеть пароль. Проверю сразу ...

Olaf Kock 26.01.2009 21:37

Извините - это вводит в заблуждение. Вам не нужно реализовывать свой собственный сервлет j_security_check, поскольку этим занимается Websphere. Используйте приведенный выше код, чтобы проверить, что выходит из этого сервлета, и предпринять действия.

jim 28.01.2009 16:40

Спецификация JavaEE не предоставляет стандартного средства для получения обратной связи об аутентификации, например кодов ошибок.

Согласно следующему IBM Redpaper об интеграции безопасности z / OS в сером примечании на стр. 57: Доступно специальное расширение IBM, чтобы страница ошибки JSP могла сообщать о конкретном сообщении (например, истек срок действия пароля) на основе кода состояния ошибки.

Согласно WebSphere InfoCenter образец FormLoginWeb из пакета TechSamp в вашей установке WebSphere (samples/src/TechSamp/FormLoginWeb) должен демонстрировать такое специфическое расширение IBM, но ... Единственное, что интересно, - это LoginFilter, который перехватывает вызовы на /j_security_check и может выполнять предварительный вход в систему проверка и действия после входа в систему, как описано в подробности в этой статье.

С помощью такого механизма можно получить исключение входа из JAAS Subject и установить код ошибки входа в HttpSession, чтобы страница ошибки могла генерировать конкретное сообщение.

«Спецификация JavaEE не предоставляет стандартного средства для получения обратной связи об аутентификации, например, кодов ошибок» А что насчет docs.oracle.com/javaee/6/api/javax/security/auth/message/…?
dexter meyers 15.02.2013 18:30

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

Yves Martin 15.02.2013 19:44

Что ж, если используется профиль моста LoginModule, исключение LoginException, которое он генерирует, должен выбрасывает соответствующий AuthException. Достаточно ли этого AuthException стандартизированной обратной связи - это, конечно, открытый вопрос.

dexter meyers 15.02.2013 21:04

ОК для базовой реализации. Теперь, как код приложения Servlet / JSP может получить исключение LoginException или AuthException, чтобы сообщить о соответствующей обратной связи пользователя на экране входа в систему?

Yves Martin 16.02.2013 15:31

Не знаю, думаю, это зависит от приложения. Может, несколько сотен тысяч? Или это слишком? Вы знаете сколько? Если я вхожу в веб-приложение (java) и ввожу неправильные учетные данные, это обычно дает мне какую-то обратную связь. Но, может быть, вы не это имеете в виду?

dexter meyers 18.02.2013 17:46

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