1

JDBA と Active Directory 認証の両方を有効にしようとしています。大きな進歩を遂げましたが、userDetailsS​​ervice が存在しない 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;
}

LdapUserDetailsS​​ervice について

@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();
    }
}

}

4

1 に答える 1

0

LDAP BIND 認証は、パスワードのハッシュ値を取得する代わりに LDAP サーバーにパスワードを送信するため、一般に、認証コンテキストでの LDAP と SQL は一緒に使用されません。

LDAP 認証の意図された手順は次のとおりです。

  • 通常、春のセキュリティ UsernamePassword フィルターは資格情報を取得するために使用され、デフォルトでアクティブになっています。たとえば、ログイン フォームを使用している場合、フォームを送信すると、このフィルターが資格情報を取得します。
  • 次に、LDAP 認証プロバイダーは、LDAP サーバー (LDAP ContextSource) に対してログイン (LDAPBindAuthenticator) を実行して資格情報を検証します。
  • ログインが成功すると、LDAP 認証プロバイダは LDAP でユーザー エントリを検索します。これは、「usersearch」Spring Bean を提供することでカスタマイズできます。
  • ユーザーエントリが見つかった場合、LDAP 権限マッパーはユーザーエントリの属性を Spring セキュリティのグループ/ロールにマップします。デフォルトでは、これはすべての OU 属性です
  • 最後に、ユーザー名と LDAP から取得したグループを使用して、新しい認証オブジェクトが作成されます。

Spring XML を使用して LDAP 認証を統合する方法については、こちらで説明されています。 http://docs.spring.io/spring-security/site/docs/3.1.x/reference/ldap.html

于 2014-05-15T14:21:07.430 に答える