spring-security: использование сертификата пользователя для аутентификации в LDAP - PullRequest
1 голос
/ 09 мая 2011

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

вот текущая конфигурация (с использованием имени пользователя сертификата):

<security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>
<bean name="userService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
    <constructor-arg ref="ldapUserSearch"/>
    <constructor-arg ref="ldapAuthoritiesPopulator"/>
</bean>
<bean name="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    <constructor-arg value=""/>
    <constructor-arg value="sAMAccountName={0}"/>
    <constructor-arg ref="contextSource" />
</bean>
<bean name="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
    <constructor-arg ref="contextSource" />
    <constructor-arg value="" />
    <property name="groupSearchFilter" value="member={0}" />
    <property name="searchSubtree" value="true" />
</bean>

Ответы [ 3 ]

1 голос
/ 16 июня 2011

Я сам искал эту проблему.Мне еще предстоит найти стек аутентификации, который делает X509-> разрешение учетной записи "правильным".Я зациклился на том факте, что интерфейс UserDetailsService Spring Security настаивает на использовании строкового идентификатора для поиска, но во многих случаях невозможно получить такой UID из информации, содержащейся в теме сертификата X509 (например, существует много cn = John Smith).в мире, или даже в пределах одной организации, и электронная почта не требуется в сертификате DN).Уникальность сертификата заключается в комбинации «эмитент + серийный номер», а не в субъекте.

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

1) Реализуйте свой собственный AuthenticationUserDetailsService и привяжите его к PreAuthenticatedAuthenticationProvider.Я полагаю, что по умолчанию пространство имен устанавливает UserDetailsByNameServiceWrapper с использованием переданного user-service-ref.Пройдя по этому маршруту, вы должны сделать все, чтобы настроить UserDetails, включая разрешение уполномоченных лиц.Конечно, вы можете делегировать все это, но это больше работы.

2) Если ваше хранилище LDAP основано на некотором UID, и это тот путь, к которому я склоняюсь, реализуйте свой собственный X509PrincipalExtractor и привяжите его кX509AuthenticationFilter и возвращает строку uid, на которую настроен ваш LDAPUserDetailsService.В экстракторе реализуйте логику для поиска сохраненного сертификата в вашем хранилище LDAP.Я не знаю каких-либо стратегий, которые будут работать на серверах LDAP, самый простой способ будет, если ваш LDAP поддерживает RFC4523 certificateMatch или certificateExactMatch, и вы можете настроить поисковый фильтр, который вернет вам уникальную учетную запись, из которой вы затем сможете вернуть атрибут, который вынужно (например, sAMAccountName).Если нет, если ваши сертификаты содержат значение, которое вы можете фильтровать (например, сертификат cn = LDAP cn), которое вы можете использовать для получения набора кандидатов результатов LDAP, извлеките их сертификаты в X509Certificate и выполните .equals () для переданногов сертификате, чтобы найти учетную запись, которая соответствует и вернуть его UID.

0 голосов
/ 17 июня 2011

Наконец, я реализовал следующее решение в своем не-веб-приложении:

<bean id="x509ContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg value="ldap://hostname:389/DC=base,DC=com" />
    <property name="authenticationStrategy">
        <bean class="org.springframework.ldap.core.support.ExternalTlsDirContextAuthenticationStrategy">
            <property name="sslSocketFactory">
                <bean class="yourOwnSocketFactory"/>
            </property>
            <property name="shutdownTlsGracefully" value="true" />
        </bean>
    </property>
</bean>

где yourOwnSocketFactory берет сертификат пользователя для установления соединения TLS.

Успешное соединение TLS означает, что пользователь аутентифицирован. Это имеет место с хорошо настроенным LDAP, который должен проверять пользователя, включая список отзыва сертификатов.

Как только соединение установлено, вы должны восстановить информацию пользователя с помощью пользовательского BindAuthenticator, который может извлечь (X509PrincipalExtractor) DN сертификата (или другую полезную информацию) для соответствия пользователю LDAP.

0 голосов
/ 10 мая 2011

Настройка сервера LDAP на использование SSL с аутентификацией клиента.

...