Новый 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, являются их собственными. |