Аутентификация в ActiveDirectory с помощью SpringSecurity

124
11 августа 2019, 19:20

Друзья, помогите, стоит задача настроить аутентификацию в ActiveDirectory с помощью Spring Security. Я не обладаю большим опытом в Spring Security и ActiveDirectory. В данный момент использую такой код:

package com.module.communication.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.event.LoggerListener;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.LdapShaPasswordEncoder;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotBlank;
import java.util.Arrays;
@Configuration
@Component
@EnableGlobalMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Value("${ldap.userSearchFilter}")
    private String userSearchFilter;
    @NotBlank
    @Value("${ldap.url}")
    private String ldapUrl;
    @NotBlank
    @Value("${ldap.domain}")
    private String ldapDomain;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .mvcMatchers("/pages/**","/assets/**")
                .permitAll()
                .anyRequest().fullyAuthenticated()
                .and()
                .formLogin().loginPage("/login").permitAll().and().csrf().disable()
                .logout().logoutSuccessUrl("/login?logout")
                .permitAll();
    }
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
    }
    @Bean
    public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        if (userSearchFilter != null && userSearchFilter.trim().length() > 0)
        {
            provider.setSearchFilter(userSearchFilter);
        }
        return provider;
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
    }
    @Bean
    public LoggerListener loggerListener() {
        return new LoggerListener();
    }
}

Код подтягивает из проперти данные об аутентификации. Если я не задаю searchFilter, то аутентификация происходит в нормальном режиме но для всех пользователей, которые содержатся в Active Directory. Однако мне необходимо аутентифицировать пользователей - членов двух определенных групп. Если я указываю любой searchFilter, то приложение начинает ругаться на любые логин и пароль, как на верные так и нет(в логе - Bad creditentials). Помогите, пожалуйста, советом как можно решить эту проблему.

Answer 1

Интуитивно предполагаю, что у тебя проблема с правильности задания userSearchFilter. Обрати внимание, что для этого параметра есть значение по умолчанию, и согласно документации оно равно (&(objectClass=user)(userPrincipalName={0})), где {0} превращается в логин@домен (или же можно использовать {1} если нужен только логин пользователя). Поэтому тебе надо делать свой фильтр расширяя указанный выше. Или же можно попробовать соединить их в runtim'е примерно так:

if (userSearchFilter != null && userSearchFilter.trim().length() > 0)
    {
    provider.setSearchFilter("(&(objectClass=user)(userPrincipalName={0})("+userSearchFilter+"))");
    }
READ ALSO
Ссылочные типы Java

Ссылочные типы Java

Я начал учить Java и не могу понять один моментПросматривая очередной видеоурок я услышал, что "При создании переменной одного из ссылочных...

111
Диалог с Сервером со стороны Kлиента

Диалог с Сервером со стороны Kлиента

Нужно чтобы клиент постоянно находился в режиме ожидания ввода команд со стороны пользователяЭти команды затем отправляются на сервер

114
Не отскакивает тело box2d

Не отскакивает тело box2d

При столкновении с другим телом ball либо останавливается, либо двигается вдоль негоВроде как это может происходить из-за неправильного world scale,...

122
Создание файла MS Word при нажатии на кнопку в графическом интерфейсе

Создание файла MS Word при нажатии на кнопку в графическом интерфейсе

Пытаюсь получить строковую переменную из "TextField" и передать ее в создаваемый файл MS Word

122