问题
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?
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/43785743/spel-not-supported-in-spring-annotation-entry-base