Spring LDAP/Active Directory с SQL

Я пытаюсь включить аутентификацию JDBA и Active Directory, я добился большого прогресса, но в настоящее время я застрял, поскольку userDetailsService пытается сравнить пароль в LdapUserDetails, которого не существует. При проверке журнала я вижу, что он может запрашивать пользователя, аутентифицировать и правильно получать роли.

Я знаю, что должен использовать bindService или около того, но до сих пор не мог найти, как это сделать.

Ниже то, что я сделал.

в WebSecurityConfigurerAdapter

@Autowired
public void configureGlobal(UserDetailsService userDetailsService,UserLdapRepositoryUserDetailsService userLdapRepositoryUserDetailsService,AuthenticationManagerBuilder auth) throws Exception {
    auth
        .userDetailsService(userDetailsService).
    and()
        .userDetailsService(userLdapRepositoryUserDetailsService);
}

Для конфигурации LDAP

    @Bean
public BaseLdapPathContextSource contextSource() {
    DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://XXXXX:389/dc=XXXXXX,dc=co");
    //contextSource.setUserDn("CN=Ali Shahbour,OU=Users,DC=XXXXXXX,DC=co");
    contextSource.setUserDn("XXXXXX");
    contextSource.setPassword("XXXXXX");
    return contextSource;
}

@Bean
@Autowired
public LdapUserSearch userSearch(BaseLdapPathContextSource contextSource) { 
    FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch("", "(uid={0})", contextSource);
    return userSearch;
}

@Bean 
@Autowired
public LdapAuthoritiesPopulator authoritiesPopulator(BaseLdapPathContextSource contextSource) {

    DefaultLdapAuthoritiesPopulator authoritiesPopulator = new DefaultLdapAuthoritiesPopulator(contextSource, "OU=CDRMonitor");

    authoritiesPopulator.setGroupSearchFilter("(member={0})");
    //authoritiesPopulator.setRolePrefix("ROLE");
    authoritiesPopulator.setSearchSubtree(true);
    //authoritiesPopulator.setConvertToUpperCase(true);

    return authoritiesPopulator;
}

Что касается LdapUserDetailsService

@Service("userLdapRepositoryUserDetailsService")
public class UserLdapRepositoryUserDetailsService extends LdapUserDetailsService {

private final UserRepository userRepository;

@Autowired
public UserLdapRepositoryUserDetailsService(LdapUserSearch userSearch,
        LdapAuthoritiesPopulator authoritiesPopulator,UserRepository userRepository) {
    super(userSearch, authoritiesPopulator);
    this.userRepository = userRepository;


}

@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    UserDetails userDetails = super.loadUserByUsername(username);
    //User user = userRepository.findByEmail(username);
    User user = new User();
    return new LdapUserRepositoryUserDetails(user, userDetails);
}

@Override
public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper) {
    super.setUserDetailsMapper(userDetailsMapper);
}

private final static class LdapUserRepositoryUserDetails extends User implements LdapUserDetails {

    private final LdapUserDetailsImpl ldapUserDetailsImpl;

    private LdapUserRepositoryUserDetails(User user,UserDetails userDetails) {
        super(user);
        ldapUserDetailsImpl = (LdapUserDetailsImpl) userDetails;
    }

    private static final long serialVersionUID = 5639683223516504866L;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return ldapUserDetailsImpl.getAuthorities();
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return ldapUserDetailsImpl.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return ldapUserDetailsImpl.isAccountNonExpired();
    }

    @Override
    public boolean isAccountNonLocked() {
        return ldapUserDetailsImpl.isAccountNonLocked();
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return ldapUserDetailsImpl.isCredentialsNonExpired();
    }

    @Override
    public boolean isEnabled() {
        return ldapUserDetailsImpl.isEnabled();
    }

    @Override
    public String getDn() {
        return ldapUserDetailsImpl.getDn();
    }
}

}


person Shahbour    schedule 15.05.2014    source источник


Ответы (1)


LDAP и SQL в контексте аутентификации обычно не используются вместе, поскольку аутентификация LDAP BIND отправляет пароль на сервер LDAP вместо получения хэш-значения пароля.

Предполагаемая процедура аутентификации LDAP выглядит следующим образом:

  • Обычно для получения учетных данных используется фильтр Spring Security UsernamePassword, который по умолчанию активен. например если вы используете форму входа, при отправке формы этот фильтр получает учетные данные.
  • Затем поставщик аутентификации LDAP выполняет вход (LDAPBindAuthenticator) на сервер LDAP (LDAP ContextSource) для проверки учетных данных.
  • Если вход в систему выполнен успешно, поставщик аутентификации LDAP ищет в LDAP запись пользователя. Это можно настроить, предоставив Spring bean-компонент usersearch.
  • Если запись пользователя найдена, сопоставитель LDAP Authority сопоставит атрибуты записи пользователя с группами/ролями в весенней безопасности. По умолчанию это все атрибуты OU.
  • Наконец, создается новый объект аутентификации с именем пользователя и извлеченными группами из LDAP.

Здесь объясняется, как интегрировать аутентификацию LDAP с использованием Spring XML. http://docs.spring.io/spring-security/site/docs/3.1.x/reference/ldap.html

person Nils    schedule 15.05.2014
comment
привет, спасибо за объяснение, сейчас мне просто нужно, чтобы Active Directory работал, но моя проблема в том, что я не могу заставить LdapUserDetailsService использовать связующее вместо того, чтобы пытаться восстановить пароль. - person Shahbour; 15.05.2014