Статьи

API безопасности Java EE 8: обзор

Новый API безопасности

Вероятно, единственная наиболее значимая новая функция, добавленная в Java EE 8, — это новый API безопасности.

Основными мотивами для этого нового API были упрощение, стандартизация и модернизация способов решения проблем безопасности в контейнерах и реализациях. И они проделали большую работу.

  • Конфигурация веб-аутентификации была модернизирована благодаря трем новым аннотациям, которые делают объявление файла web.xml избыточным.
  • Новый API контекста безопасности стандартизирует способ аутентификации сервлета и контейнера EJB и
  • Новая абстракция Identity S tore упрощает использование хранилищ идентификаторов.

А пока давайте посмотрим на первую из этих новых функций.

Механизм аутентификации на основе аннотаций

Эта функция предназначена для настройки веб-безопасности. Какая традиционная требуется декларация XML в файле web.xml .

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

Они запускаются с использованием одной из этих аннотаций.

1
2
3
@BasicAuthenticationMechanismDefinition
@FormAuthenticationMechanismDefinition
@CustomFormAuthenticationMechanismDefinition

Они дублируют функциональность классической HTTP-аутентификации, аутентификации на основе форм и пользовательских форм, уже доступной в контейнере сервлетов.

Например, чтобы включить обычную аутентификацию, все, что нужно, это добавить аннотацию BasicAuthenticationMechanismDefinition в ваш сервлет и все.

1
2
3
4
5
@BasicAuthenticationMechanismDefinition(realmName="${'user-realm'}")
@WebServlet("/user")
@DeclareRoles({ "admin", "user", "demo" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "user"))
public class UserServlet extends HttpServlet { … }

Теперь вы можете выбросить свои XML-конфигурации и использовать одну из этих новых аннотаций для обеспечения веб-безопасности.

Следующая замечательная особенность API безопасности — абстракция хранилища идентификаторов.

Фирменный стиль Абстракция

Хранилище идентификационных данных — это база данных, в которой хранятся идентификационные данные пользователя, такие как имя пользователя, членство в группах и информация, используемая для проверки учетных данных.

Новый API безопасности Java EE предоставляет абстракцию хранилища идентификаторов, называемую IdentityStore, которая используется для взаимодействия с хранилищами идентификаторов для аутентификации пользователей и получения членства в группах и схожа с интерфейсом JAAS LoginModule .

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

Тем не менее, совместное использование IdentityStore и HttpAuthenticationMechanism позволяет приложению управлять хранилищами идентификаторов, которые оно использует для аутентификации, переносимым и стандартным способом и является рекомендуемым способом для большинства сценариев использования.

Теперь вы можете реализовать свое собственное хранилище идентификаторов, реализовав интерфейс IdentityStore, или вы можете использовать одну из встроенных реализаций IdentityStore для LDAP и реляционных баз данных. Они инициализируются путем передачи сведений о конфигурации в соответствующую аннотацию @LdapIdentityStoreDefinition или @DataBaseIdentityStoreDefinition .

Давайте рассмотрим использование встроенного хранилища идентификаторов.

Самым простым хранилищем идентификаторов является хранилище базы данных. Он настраивается с помощью аннотации @DataBaseIdentityStoreDefinition, как показано ниже.

01
02
03
04
05
06
07
08
09
10
11
@DatabaseIdentityStoreDefinition(
  dataSourceLookup = "${'java:global/permissions_db'}",
  callerQuery = "#{'select password from caller where name = ?'}",
  groupsQuery =
     "select group_name from caller_groups where caller_name = ?",
  hashAlgorithm = PasswordHash.class,
  priority = 10
)
@ApplicationScoped
@Named
public class ApplicationConfig { ... }

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

Однако обратите внимание на приоритет, установленный на 10, это используется в случае, если во время выполнения найдено несколько хранилищ идентификаторов, и определяет порядок итераций относительно других хранилищ. Меньшие числа имеют более высокий приоритет.

Теперь давайте посмотрим, что является последней новой функцией API безопасности.

Контекст безопасности

Цель контекста безопасности — обеспечить согласованный доступ к контексту безопасности через сервлет и контейнеры EJB.

В настоящее время эти контейнеры реализуют объекты контекста безопасности непоследовательно. Например, контейнер сервлета предоставляет экземпляр HttpServletRequest, для которого вызывается метод getUserPrincipal () для получения принципала пользователя , а контейнер EJB предоставляет экземпляр EJBContext с другим именем, для которого вызывается метод с тем же именем. И также, чтобы проверить, принадлежит ли пользователь определенной роли, метод isUserRole () вызывается в экземпляре HttpServletRequest, а isCallerInRole () вызывается в экземпляре EJBContext .

SecurityContext обеспечивает согласованность между сервлетом и контейнером EJB для получения такого рода информации. Он имеет пять методов, и ни один из них не имеет реализации по умолчанию.

Principal getCallerPrincipal (); Возвращает платформенно-зависимый принципал, представляющий имя текущего аутентифицированного пользователя, или ноль, если текущий вызывающий абонент не аутентифицирован.

<T расширяет принципала> Set <T> getPrincipalsByType (Class <T> pType); Возвращает все Принципалы данного типа из Субъекта вызывающего абонента , в противном случае возвращается пустой Набор, если ни тип pType не найден, либо текущий пользователь не аутентифицирован.

логическое isCallerInRole (строковая роль); Определяет, включен ли вызывающий в указанную роль, в противном случае он возвращает false, если пользователь не авторизован.

логический hasAccessToWebResource (ресурс String, методы String…); Определяет, имеет ли вызывающая сторона доступ к данному веб-ресурсу с помощью предоставленных методов.

AuthenticationStatus authenticate (HttpServletRequest req, HttpServletResponse res, параметр AuthenticationParameters); Сообщает контейнеру, что он должен начать или продолжить диалог аутентификации на основе HTTP с вызывающей стороной. Этот метод работает только в контейнере сервлета из-за его зависимости от экземпляров HttpServletRequest и HttpServletResponse .

Контекст безопасности является компонентом CDI и поэтому может быть вставлен в любой класс в сервлете и контейнере EJB.

1
2
@Inject
private SecurityContext securityContext;

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

1
2
boolean hasAccess = securityContext 
    .hasAccessToWebResource("/secretServlet", "GET");

Теперь, когда мы завершили этот обзор API безопасности, есть еще много информации о API безопасности.

Опубликовано на Java Code Geeks с разрешения Алекса Тидома, партнера нашей программы JCG. См. Оригинальную статью здесь: API безопасности Java EE 8: обзор

Мнения, высказанные участниками Java Code Geeks, являются их собственными.