I use Spring Data LDAP and Spring Boot provides out of the box support for an embedded UnboundID server. However, when I use Spring Data LDAP's @Entry
annotation, I need to specify a different base
in the annotation based on whether I'm using the embedded UnboundID LDAP server, or a remote Active Directory server.
I was attempting to do this with SpEL and profile-based properties by specifying:
@Entry(base = "${ldap.person.base}", ...)
Then I have an application.propreties
with ldap.person.base=OU=AD Person Base
and an application-embedded.properties
with ldap.person.base=OU=Embedded Person Base
.
However, the @Entry
annotation does not seem to support SpEL evaluation:
javax.naming.InvalidNameException: Invalid name: ${ldap.person.base}
There is an open issue in Spring LDAP to add support for this, but is there any workaround or some other way I can accomplish this until it is supported in Spring LDAP?
I'm not sure I'm following here, but assuming you're using the LDAP auto-configuration in Spring Boot, is it not enough to set the property spring.ldap.base
to one or the other (OU=AD Person Base
or OU=Embedded Person Base
) based on the profile you're using?
Both EmbeddedLdapAutoConfiguration
and LdapAutoConfiguration
use an LdapProperties
object to set various attributes on the LdapContextSource
during bean creation, including its base
. As far as I can tell, you won't have to define it for each @Entry
in your codebase if LdapContextSource.base
is set.
If you're not using the auto-configuration, and if I'm correct in my assumptions, you should still be able to create your own LdapContextSource
bean and set its base
to the desired value based on a Spring property.
Turns out the reason I needed a different base
in the first place is because Spring was not setting the base
on the ContextSource
.
When you let Spring Boot autoconfigure the embedded LDAP server, it creates a ContextSource
as such in EmbeddedLdapAutoConfiguration
:
@Bean
@DependsOn("directoryServer")
@ConditionalOnMissingBean
public ContextSource ldapContextSource() {
LdapContextSource source = new LdapContextSource();
if (hasCredentials(this.embeddedProperties.getCredential())) {
source.setUserDn(this.embeddedProperties.getCredential().getUsername());
source.setPassword(this.embeddedProperties.getCredential().getPassword());
}
source.setUrls(this.properties.determineUrls(this.environment));
return source;
}
As you can see, nowhere in there does it call source.setBase()
. So to solve this, I added a configuration file with @Profile("embedded")
and manually created a ContextSource
where I set the base
myself (I leave off the credentials part because I don't use credentials for the embedded server):
@Configuration
@Profile("embedded")
@EnableConfigurationProperties({ LdapProperties.class })
public class EmbeddedLdapConfig {
private final Environment environment;
private final LdapProperties properties;
public EmbeddedLdapConfig(final Environment environment, final LdapProperties properties) {
this.environment = environment;
this.properties = properties;
}
@Bean
@DependsOn("directoryServer")
public ContextSource ldapContextSource() {
final LdapContextSource source = new LdapContextSource();
source.setUrls(this.properties.determineUrls(this.environment));
source.setBase(this.properties.getBase());
return source;
}
}
Now, I can leave the value of the base
attribute in my @Entry
the same for both the Active Directory server and the embedded UnboundID server and it works properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With