Dzak
Dzak

Reputation: 213

How to read operational attributes from ldap server

I have to read operational attributes from the LDAP server (createTimeStamp, entryUUID etc).

I have tried to implement own UserDetailContextMapper but without success.

At the moment my code looks like this

Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .ldapAuthentication()
            .userSearchFilter("uid={0}")
            .groupSearchBase("ou=users")
            .userDetailsContextMapper(userContextMapper())
            .contextSource(contextSource());
}

@Bean
public LdapContextSource contextSource() {
    LdapContextSource contextSource = new LdapContextSource();
    contextSource.setUrl("ldap://ldap.company.pl:389");
    contextSource.setBase("dc=company,dc=com");
    contextSource.afterPropertiesSet();
    return contextSource;
}

@Bean
public UserDetailsContextMapper userContextMapper() {
    return new CustomUserDetailContextMapper();
}

My UserDetailContextMapper implementation:

public class CustomUserDetailContextMapper implements UserDetailsContextMapper {

@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<?
        extends GrantedAuthority> authorities) {
    AutoUser user = new AutoUser();

    user.setCreateTimeStamp(ctx.getStringAttribute("createTimestamp"));
    user.setUUID(ctx.getStringAttribute("entryUUID"));
    user.setEmail(ctx.getStringAttribute("mail"));
    return user;
}

@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
    //default impl
}

}

I've tried Attributes attributes = ctx.getAttributes(username, new String[] {"*", "+"});

in mapUserFromContext() method, but I'm receiving NamingException if i pass username.

I was thinking about implementing ldapTemplate.lookup(), but I'm not really sure where to implement it, I've tried to do userRepo class with ldapTemplate, but I got NameNotFoundException with any DN I pass.

StackTrace for namingException from ctx.getAttributes()

javax.naming.NameNotFoundException
at org.springframework.ldap.core.DirContextAdapter.getAttributes(DirContextAdapter.java:865)
at pl.consileon.training.config.CustomUserDetailContextMapper.mapUserFromContext(CustomUserDetailContextMapper.java:21)
at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:87)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

I can retrieve object from LDAP using query like that:

public Object getAll(){
    return ldapTemplate.search(query()
    .where("entryUUID").is("<HasToPassUUIDFromLDAP"), new PersonAttributesMapper());
}

but I need to pass full attribute value, which is not the point since i want to retrieve this value, not the object with this value.

Upvotes: 1

Views: 2747

Answers (1)

Filip Hanik VMware
Filip Hanik VMware

Reputation: 1622

    ctx.getAttributes(username, new String[] {"*", "+"});
  1. username - according to the documentation, this should be the DN That's how LDAP knows which record you're pulling data from

  2. The second parameter, if you set it to null, it will retrieve all attributes

I believe your error is thrown because you're passing in a username instead of a distinguished name.

    /**
     * Retrieves selected attributes associated with a named object.
     * See {@link #getAttributes(Name, String[])} for details.
     *
     * @param name
     *          The name of the object from which to retrieve attributes
     * @param attrIds
     *          the identifiers of the attributes to retrieve.
     *          null indicates that all attributes should be retrieved;
     *          an empty array indicates that none should be retrieved.
     * @return  the requested attributes; never null
     *
     * @throws  NamingException if a naming exception is encountered
     */
    public Attributes getAttributes(String name, String[] attrIds)
            throws NamingException;

Upvotes: 1

Related Questions