2013-05-23 6 views
19

Я проводил некоторое время, оценивая параметры, доступные для надежной аутентификации пользователя в приложении Java EE.Проверка подлинности RESTful для 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> 

Преимущества

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

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

  3. Простота установки.

Недостатки

  1. логофф сложно реализовать. См. here и here. Убедитесь, что у вас есть хороший запрос AJAX, который аутентифицирует пользователя, но вам также нужно иметь AJAX? запрос, который отходит от пользователя, - чтобы снова появиться окно входа в браузер). BTW хороший сервлет 3.0 request.logout() метод does not work properly in this case.
  2. Тайм-ауты сеанса очень трудно реализовать. Истекает истечение сеанса (это задача контейнера сервлета), но браузер отправляет заголовки полномочий по следующему запросу, инициируя повторную аутентификацию.
  3. Нет персонализированной страницы входа. Никто.
  4. Трудно отслеживать заверенные сеансы.

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> 

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

Преимущества

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

Недостатки

  1. REST недружелюбно (я не собираюсь копаться в ФИЛОСОФИЯ отдыха и поддержанию на стороне сервера государства не RESTful дебаты. Мы анализа подлинности REST в Режим JAVA EE и серверное состояние всегда поддерживаются для любого объекта, прошедшего проверку подлинности). Что действительно плохо в использовании проверки подлинности FORM - это тот факт, что в браузерах не может быть последовательного поведения. И все это связано с перенаправлением 302, которое некоторые браузеры обрабатывают в функциях ответа AJAX, а другие перенаправляют всю страницу (изменение URL-адреса в навигационной панели). Подробнее here и here. Вы не можете обойти это перенаправление 302, так что для вас не будет никакой проверки FORM и REST !!

3. Programmatic аутентификации

Настройка 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()); 

Преимущества

  1. персонализированного Войти страницу.
  2. AJAX/REST совместимый
  3. Выход URL (если URL настроен сделать это)
  4. время ожидания сеанса (контейнер под управлением)
  5. Вы можете вернуть регистрационные данные (имя пользователя, адрес электронной почты, роли, группы и т.д. .) в ответ (reaaaallly хороший, потому что вы не должны делать еще один вызов после успешной регистрации)

Недостатки

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

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

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

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

+1

Возможно, один вариант Java EE, который вы не упомянули, - JASPIC. Это доступно в полном профиле Java EE 6 и дает вам большую свободу в том, как вы организуете аутентификацию. –

+0

Честно говоря, я не пошел бы с JASPIC, потому что он недостаточно зрелый. Кстати хороший учебник по JASPIC @Arjan. – victor

+0

Ничего себе, нет любви по этому вопросу. Я хотел бы узнать больше. Очень хороший вопрос. – mikato

ответ

0

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

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

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

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

3

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

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

Смежные вопросы