Jer*_*nce 10 spring placeholder spring-security
我已经使用ldap服务器配置了spring security(但是继续读取,如果你不了解它就不是问题,这真的是一个春天的问题).所有的运行都像一个魅力.这是我用于此的行:
<ldap-server ldif="" root="" manager-dn="" manager-password="" url="" id="ldapServer" />
Run Code Online (Sandbox Code Playgroud)
如果我填写ldif和root属性,它将运行一个embeded服务器:
<ldap-server ldif="classpath://ldap.ldif" root="dc=springframework,dc=org" manager-dn="" manager-password="" url="" id="ldapServer" />
Run Code Online (Sandbox Code Playgroud)
如果我填写其他字段,它将运行一个远程服务器:
<ldap-server ldif="" root="" manager-dn="dc=admin,dc=springframeworg,dc=org" manager-password="password" url="ldap://myldapserver.com/dc=springframeworg,dc=org" id="ldapServer" />
Run Code Online (Sandbox Code Playgroud)
所有这些东西都运行正常.现在我想使用Spring机制从属性文件加载这些参数:
所以我替换这样的属性值:
<ldap-server ldif="${ldap.ldif.path}" root="${ldap.ldif.root}" manager-dn="${ldap.server.manager.dn}" manager-password="${ldap.server.manager.password}" url="${ldap.server.url}" id="ldapServer" />
Run Code Online (Sandbox Code Playgroud)
并创建一个属性文件:
ldap.server.url=
ldap.server.manager.dn=
ldap.server.manager.password=
ldap.ldif.path=
ldap.ldif.root=
Run Code Online (Sandbox Code Playgroud)
现在,问题的有趣部分.如果我在文件中填写以下属性:
ldap.server.url=ldap://myldapserver.com/dc=springframeworg,dc=org
ldap.server.manager.dn=dc=admin,dc=springframeworg,dc=org
ldap.server.manager.password=password
ldap.ldif.path=
ldap.ldif.root=
Run Code Online (Sandbox Code Playgroud)
它按预期运行远程服务器.
如果我像这样填写属性文件:
ldap.server.url=
ldap.server.manager.dn=
ldap.server.manager.password=
ldap.ldif.path= classpath:ldap.ldif
ldap.ldif.root= dc=springframeworg,dc=org
Run Code Online (Sandbox Code Playgroud)
它没有运行,抱怨ldap url丢失了.但问题是如果我改变弹簧配置:
<ldap-server ldif="${ldap.ldif.path}" root="${ldap.ldif.root}" manager-dn="${ldap.server.manager.dn}" manager-password="${ldap.server.manager.password}" url="${ldap.server.url}" id="ldapServer" />
Run Code Online (Sandbox Code Playgroud)
to(通过删除对变量$ {ldap.server.url}的引用)
<ldap-server ldif="${ldap.ldif.path}" root="${ldap.ldif.root}" manager-dn="${ldap.server.manager.dn}" manager-password="${ldap.server.manager.password}" url="" id="ldapServer" />
Run Code Online (Sandbox Code Playgroud)
它运行!
我的意思是,如果这个属性为空,那么spring不会用属性config替换属性值.但我觉得很奇怪.
你能给我一些线索来理解吗?通过属性文件配置我的ldap服务器最好的做法是什么?
编辑:这是由于糟糕的设计选择(看看接受的答案),jira已经开启了一个问题:https: //jira.springsource.org/browse/SEC-1966
好吧,我认为这是一个 Spring 安全错误。
如果我调试并查看 LdapServerBeanDefinition 类,就会发现有一个名为“parse”的方法。这是摘录:
public BeanDefinition parse(Element elt, ParserContext parserContext) {
String url = elt.getAttribute(ATT_URL);
RootBeanDefinition contextSource;
if (!StringUtils.hasText(url)) {
contextSource = createEmbeddedServer(elt, parserContext);
} else {
contextSource = new RootBeanDefinition();
contextSource.setBeanClassName(CONTEXT_SOURCE_CLASS);
contextSource.getConstructorArgumentValues().addIndexedArgumentValue(0, url);
}
contextSource.setSource(parserContext.extractSource(elt));
String managerDn = elt.getAttribute(ATT_PRINCIPAL);
String managerPassword = elt.getAttribute(ATT_PASSWORD);
if (StringUtils.hasText(managerDn)) {
if(!StringUtils.hasText(managerPassword)) {
parserContext.getReaderContext().error("You must specify the " + ATT_PASSWORD +
" if you supply a " + managerDn, elt);
}
contextSource.getPropertyValues().addPropertyValue("userDn", managerDn);
contextSource.getPropertyValues().addPropertyValue("password", managerPassword);
}
...
}
Run Code Online (Sandbox Code Playgroud)
如果我在这里调试,所有变量(url、managerDn、managerPassword...)都不会被属性文件中指定的值替换。因此,url 的值为 ${ldap.server.url},managerDn 的值为 ${ldap.server.manager.dn} 等等。
parse 方法创建一个 bean,一个将被进一步使用的上下文源。当使用这个 bean 时,占位符将被替换。
在这里,我们遇到了错误。parse 方法检查 url 是否为空。问题是 url 这里不为空,因为它的值为 ${ldap.server.url}。因此,解析方法创建一个上下文源作为远程服务器。
当使用创建的源时,它将用空值替换 ${ldap.server.url} (如属性文件中指定的)。还有……虫子!
我暂时不知道如何解决这个问题,但我现在明白为什么它会出错;)
| 归档时间: |
|
| 查看次数: |
5473 次 |
| 最近记录: |