Подтвердить что ты не робот

Аутентификация RESTful для Java EE

Я проводил некоторое время, оценивая параметры, доступные для надежной аутентификации пользователя в приложении Java EE.

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

1. Проверка подлинности DIGEST/BASIC

 <security-constraint>
     <web-resource-collection>
        <web-resource-name>admin</web-resource-name>
        <url-pattern>/protected/*</url-pattern>
     </web-resource-collection>
     <auth-constraint>
        <role-name>admin</role-name>
     </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>DIGEST/BASIC</auth-method>
    <realm-name>as-defined-secuity-realm</realm-name>
</login-config>

<сильные > Преимущества

  • Это дружественный способ проверки подлинности REST. Вы можете отправить учетные данные авторизации с помощью вызова AJAX. После аутентификации пользователя браузер будет сопровождать любые запросы соответствующим заголовком Authorization: Basic/Digest QWxhZGRpbjpvcGVuIHNlc2FtZQ==. В случае неправильных учетных данных пользователю будет представлен экран уродливого браузера - если вы можете жить с этим, то для вас будет использоваться пароль BASIC/DIGEST.

  • В случае Digest строка, переданная на сервер, представляет собой зашифрованную строку MD5, которая, безусловно, более безопасна, чем Basic (которая является кодировкой Base64 строки "user: password" ), но тем не менее decipherable. Таким образом, с точки зрения безопасности BASIC в значительной степени безопасен как аутентификация FORM, а DIGEST - самый безопасный из всех. В заключение, если ваш сайт полностью HTTPS (я имею в виду полностью, потому что, если некоторые ресурсы извлекаются через HTTP, ваши заголовки полномочий, например, будут видны третьей стороне), вы можете безопасно использовать BASIC/DIGEST,

  • Простота настройки.

Недостатки

  • Выход из системы сложный для реализации. См. здесь и здесь. Убедитесь, что у вас есть хороший запрос AJAX, который аутентифицирует пользователя, но вам также нужно иметь AJAX? запрос, который отходит от пользователя, - чтобы снова появиться окно входа в браузер). Кстати, хороший сервлет 3.0 request.logout() метод не работает должным образом в этом случае.
  • Тайм-ауты сеанса очень трудно реализовать. Завершение сеанса происходит (это задача контейнера сервлета), но браузер отправляет заголовки полномочий на следующий запрос, инициируя повторную аутентификацию.
  • Нет персонализированной страницы входа. Никто.
  • Трудно отслеживать заверенные сеансы.

2. Аутентификация на основе FORM

 <security-constraint>
     <web-resource-collection>
        <web-resource-name>admin</web-resource-name>
        <url-pattern>/protected/*</url-pattern>
     </web-resource-collection>
     <auth-constraint>
        <role-name>admin</role-name>
     </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>as-defined-security-realm</realm-name>
    <form-login-config>
        <form-login-page>/auth/login.html</form-login-page>
        <form-error-page>/auth/error.html</form-error-page>
    </form-login-config>
</login-config>

Короче говоря, если пользователь обращается к URL-адресу protected/*, страница входа в систему включена в ответ. Поэтому вместо содержимого, которое пользователь ожидает, он получит страницу входа, настроенную в теге form-login-page. Если пароль в порядке, он будет перенаправлен (302 Paged Moved Permently) на первоначально запрошенный URL protected/*. Если пароль NOK, пользователь будет перенаправлен (302 Paged Moved Permently) на страницу с ошибкой.

<сильные > Преимущества

  • Персонализированная страница входа - эта, по-видимому, самая популярная:)
  • Выйти легко. Нужно только аннулировать HttpSession или вызвать метод request.logout() (Servlet 3.0).
  • Тайм-ауты сеанса
  • ЕСЛИ И ТОЛЬКО Если вы принимаете отдельную страницу для входа, это решение для вас.

Недостатки

  • ОТДЫХ недружественный (я не собираюсь копаться в философии отдыха, и сохранение состояния на стороне сервера не является дебатом RESTful. Мы анализируем аутентификацию REST в режиме JAVA EE, а состояние на стороне сервера всегда поддерживается для любых аутентифицированный субъект). Что действительно плохо в использовании проверки подлинности FORM - это тот факт, что в браузерах не может быть последовательного поведения. И все это связано с перенаправлением 302, которое некоторые браузеры обрабатывают в функциях ответа AJAX, а другие перенаправляют всю страницу (изменение URL-адреса в навигационной панели). Подробнее здесь и здесь. Вы не можете обойти это перенаправление 302, так что для вас не будет никакой проверки FORM и REST!!

3. Программная аутентификация

Настройте URL-адрес для проверки подлинности. За этим URL-адресом вы можете иметь сервлет, который создает экземпляр модуля входа в систему (путь JAAS) и вызывает метод HttpServletRequest.login(пользователь, пропуск) вместе с учетными данными. Он должен генерировать ответ 401/403, если логин завершился неудачно.

Вы можете реализовать его, просто указав ограничения безопасности в вашем web.xml:

<security-constraint>
     <web-resource-collection>
        <web-resource-name>admin</web-resource-name>
        <url-pattern>/protected/*</url-pattern>
     </web-resource-collection>
     <auth-constraint>
        <role-name>admin</role-name>
     </auth-constraint>
</security-constraint>

На стороне сервера вам просто нужно настроить службу RESTFul, которая проверяет подлинность вызывающего абонента. Вот пример кода:

@Path("/auth")
@ApplicationPath("/rest")
public class AuthenticationRestFacade {

@POST
@Path("/login")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public User login(User loginInfo, @Context HttpServletRequest request) throws LoginException, ServletException {

    // nasty work-around for Catalina AuthenticatorBase to be able to 
    // change/create the session cookie 
    request.getSession();
    request.login(loginInfo.getName(), loginInfo.getPassword());

<сильные > Преимущества

  • Персональная страница входа.
  • Совместимость AJAX/REST
  • URL выхода (если для этого настроен URL-адрес)
  • Тайм-ауты сеанса (управление контейнером)
  • В ответе вы можете вернуть данные входа (имя пользователя, адрес электронной почты, роли, группы и т.д.) (хорошо, потому что вам не нужно делать другой звонок после успешного входа в систему)

Недостатки

  • Нуждается в написании кода.
  • Требуется, чтобы приложение могло обрабатывать ответы 401/403 и отображать окно входа в систему.

В заключение, лучшие жизнеспособные варианты:

  • Если вам не нужны таймауты сеанса или выход из системы → DIGEST
  • Если приведенное выше не работает для вас. И вам не нужно иметь встроенную страницу входа (или страницу с моделями на панели), и с тобой все в порядке с одной страницей для аутентификации → FORM
  • Если вышеуказанное не работает для вас, и вы хотите, чтобы вся гибкость и совместимость в мире шли с помощью подхода PROGRAMMATIC. Вы должны определить URL входа/выхода из системы, а также ваш код клиента должен иметь возможность справиться с ответами 401/403 (не просто).

Надеюсь, вы, ребята, предложите некоторые жизнеспособные альтернативные решения. Потому что сейчас я бы НЕНАВИЖУ пойти с помощью подхода ПРОГРАММЫ

4b9b3361

Ответ 1

В моем опыте трудно внедрить систему, использующую службу аутентификации и авторизации Java EE, которая будет работать как для служб REST, так и для MVC на стороне сервера, например JSP или JSF. Весь мой опыт направлен на использование аутентификации на основе форм для части MVC и некоторую аутентификацию токена (OAuth, Kerberos, LTPA) для служб REST. Использование формальной или базовой аутентификации для служб REST обычно было сложным для реализации, хотя мы это сделали, и он отлично работает в двух проектах.

Это также зависит от предпочтительной реализации сервера.

Ответ 2

Возможно спорно ли это RESTful, но было бы хорошо, по крайней мере, включать следующее:

Как насчет Кебероса? Использование сервера аутентификации, такого как Windows AD...

Как насчет сертификатов открытого ключа? Опираясь на предоставленные клиентом сертификаты для идентификации пользователя...

Как насчет токенов? Сторонние маркеры, такие как OpenID...