Question

I am trying to enable both JDBA and Active Directory Authentication , i made great progress but currently i am stuck as userDetailsService is trying to compare the password in LdapUserDetails which does not exist . When checking the log i see it is able to query the user and authenticate and get the roles correctly.

I know i should use bindService or so , but i couldn't find till now how to do that.

Below is what i did .

in WebSecurityConfigurerAdapter

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

For LDAP Configuration

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

As for the 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();
    }
}

}

Était-ce utile?

La solution

LDAP and SQL in an authentication context are in general not used together, because LDAP BIND authentication sends the password to the LDAP server instead of retrieving a hash value of the password.

The intended procedure of LDAP Authentication is as follows:

  • Usually a spring security UsernamePassword filter is used to pick up the credentials and is active by default. e.g. if you us a login form, when submitting the form, this filter picks up the credentials.
  • Next an LDAP Authentication Provider performs a login (LDAPBindAuthenticator) against the LDAP server (LDAP ContextSource) to verify the credentials.
  • If the login is successful, the LDAP Authentication Provider searches the LDAP for a user entry. This can be customised by providing a 'usersearch' spring bean.
  • If the user entry is found, the LDAP Authority mapper will map attributes of the user entry to groups/roles in spring security. By default this are all OU attributes
  • Lastly a new authentication object is made with the username and retrieved groups from the LDAP.

How to integrate LDAP Authentication using Spring XML is explained here. http://docs.spring.io/spring-security/site/docs/3.1.x/reference/ldap.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top