Spring Security предусматривает пакет, способный делегировать запросы на аутентификацию сервису Аутентификации и Авторизации Java (JAAS). Этот пакет подробно описан ниже.
AbstractJaasAuthenticationProvider
AbstractJaasAuthenticationProvider
является основой для предусмотренных реализаций AuthenticationProvider
в JAAS. Подклассы должны реализовать метод, который создает LoginContext
. AbstractJaasAuthenticationProvider
имеет ряд зависимостей, которые могут быть введены в него и которые описаны ниже.
JAAS CallbackHandler
Большинству LoginModule
из JAAS требуется какой-то тип обратного вызова. Эти обратные вызовы обычно используются для получения имени пользователя и пароля от пользователя.
При развертывании с использованием Spring Security, Spring Security отвечает за это взаимодействие с пользователем (через механизм аутентификации). Таким образом, к моменту передачи запроса аутентификации в JAAS, механизм аутентификации Spring Security уже полностью заполнит объект Authentication
, содержащий всю информацию, необходимую LoginModule
из JAAS.
Поэтому пакет JAAS для Spring Security содержит два стандартных обработчика обратных вызовов, JaasNameCallbackHandler
и JaasPasswordCallbackHandler
. Каждый из этих обработчиков обратного вызова реализует JaasAuthenticationCallbackHandler
. В большинстве случаев эти обработчики обратного вызова можно просто использовать и не разбираться в их внутренней механике.
Для тех, кому требуется полный контроль над логикой работы обратного вызова, на внутреннем уровне AbstractJaasAuthenticationProvider
обёртывает эти экземпляры JaasAuthenticationCallbackHandler
с помощью InternalCallbackHandler
. InternalCallbackHandler
– это класс, который фактически реализует обычный интерфейс CallbackHandler
из JAAS. При каждом использовании LoginModule
из JAAS ему передается список экземпляров InternalCallbackHandler
, сконфигурированных в контексте приложения. Если LoginModule
запрашивает обратный вызов для InternalCallbackHandlers
, обратный вызов, в свою очередь, передается обертываемым экземплярам JaasAuthenticationCallbackHandler
.
JAAS AuthorityGranter
JAAS работает с принципалами. В JAAS даже "роли" представлены в виде принципалов. Spring Security, с другой стороны, работает с объектами Authentication
. Каждый объект Authentication
содержит одного принципала и несколько GrantedAuthority
. Чтобы упростить сопоставление между этими различными понятиями, пакет JAAS в Spring Security содержит интерфейс AuthorityGranter
.
AuthorityGranter
отвечает за проверку принципала JAAS и возвращает набор String
, представляющих полномочия, переданные принципалу. Для каждой возвращенной строки разрешений, AbstractJaasAuthenticationProvider
создает JaasGrantedAuthority
(который реализует интерфейс GrantedAuthority
из Spring Security), содержащий строку полномочий и принципала JAAS, который был передан AuthorityGranter
. AbstractJaasAuthenticationProvider
получает принципалов JAAS, сначала успешно аутентифицируя учетные данные пользователя с помощью LoginModule
из JAAS, а затем обращаясь к возвращаемому LoginContext
. Выполняется вызов LoginContext.getSubject().getPrincipals()
, при этом каждый полученный принципал передается каждому AuthorityGranter
, определенному в свойстве AbstractJaasAuthenticationProvider.setAuthorityGranters(List)
.
Spring Security не содержит никаких производственных AuthorityGranters
, поскольку каждый принципал JAAS имеет специфическое для конкретной реализации значение. Однако в модульных тестах есть TestAuthorityGranter
, который наглядно демонстрирует работу простой реализации AuthorityGranter
.
DefaultJaasAuthenticationProvider
DefaultJaasAuthenticationProvider
позволяет внедрить в него JAAS-объект Configuration
в качестве зависимости. Затем он создает LoginContext
, используя внедренную Configuration
из JAAS. Это значит, что DefaultJaasAuthenticationProvider
не связан с какой-то конкретной реализацией Configuration
, как JaasAuthenticationProvider
.
InMemoryConfiguration
Чтобы упростить внедрение Configuration
в DefaultJaasAuthenticationProvider
, по умолчанию предусмотрена размещаемая в оперативной памяти реализация с именем InMemoryConfiguration
. Конструктор реализации принимает Map
, в которой каждый ключ представляет имя конфигурации входа в систему, а значение – Array
, состоящий из AppConfigurationEntry
. InMemoryConfiguration
также поддерживает стандартный Array
, состоящий из объектов AppConfigurationEntry
, который будет использован, если не будет найдено отображение в указанной Map
. За подробностями обратитесь к javadoc на уровне классов по InMemoryConfiguration
.
Пример конфигурации DefaultJaasAuthenticationProvider
Хотя конфигурация Spring для InMemoryConfiguration
может быть более перегруженной, чем стандартные конфигурационные JAAS-файлы, ее использование в сочетании с DefaultJaasAuthenticationProvider
является более гибким, чем использование JaasAuthenticationProvider
, поскольку она не зависит от стандартной реализации Configuration
.
Ниже приведен пример конфигурации DefaultJaasAuthenticationProvider
с использованием InMemoryConfiguration
. Обратите внимание, что кастомные реализации Configuration
с легкостью можно внедрить и в DefaultJaasAuthenticationProvider
.
<bean id="jaasAuthProvider"
class="org.springframework.security.authentication.jaas.DefaultJaasAuthenticationProvider">
<property name="configuration">
<bean class="org.springframework.security.authentication.jaas.memory.InMemoryConfiguration">
<constructor-arg>
<map>
<!--
SPRINGSECURITY является loginContextName по умолчанию
для AbstractJaasAuthenticationProvider
-->
<entry key="SPRINGSECURITY">
<array>
<bean class="javax.security.auth.login.AppConfigurationEntry">
<constructor-arg value="sample.SampleLoginModule" />
<constructor-arg>
<util:constant static-field=
"javax.security.auth.login.AppConfigurationEntry$LoginModuleControlFlag.REQUIRED"/>
</constructor-arg>
<constructor-arg>
<map></map>
</constructor-arg>
</bean>
</array>
</entry>
</map>
</constructor-arg>
</bean>
</property>
<property name="authorityGranters">
<list>
<!-- Необходимо будет написать собственную реализацию AuthorityGranter -->
<bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
</list>
</property>
</bean>
JaasAuthenticationProvider
JaasAuthenticationProvider
предполагает, что стандартная Configuration
является экземпляром ConfigFile. Такое предположение делается для того, чтобы предпринимать попытки обновить Configuration
. Затем JaasAuthenticationProvider
использует стандартную Configuration
для создания LoginContext
.
Предположим, что у нас есть конфигурационный JAAS-файл для входа в систему, /WEB-INF/login.conf
, со следующим содержимым:
JAASTest {
sample.SampleLoginModule required;
};
Как и все бины Spring Security, JaasAuthenticationProvider
конфигурируется через контекст приложения. Следующие определения будут соответствовать приведенному выше конфигурационному JAAS-файлу входа в систему:
<bean id="jaasAuthenticationProvider"
class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
<property name="loginConfig" value="/WEB-INF/login.conf"/>
<property name="loginContextName" value="JAASTest"/>
<property name="callbackHandlers">
<list>
<bean
class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
<bean
class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler"/>
</list>
</property>
<property name="authorityGranters">
<list>
<bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
</list>
</property>
</bean>
Выполнение в качестве Subject
JaasApiIntegrationFilter
– если добавлен в конфигурацию – будет пытаться выполняться как Subject
для JaasAuthenticationToken
. Это означает, что доступ к Subject
можно получить с помощью:
Subject subject = Subject.getSubject(AccessController.getContext());
Эту интеграцию можно с легкостью сконфигурировать при помощи атрибута jaas-api-provision. Эта функция полезна при интеграции с устаревшими или внешними API, которые основываются на заполнении JAAS-субъекта.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ