我不熟悉Grails,并且在使用Spring Security LDAP插件时,发现它仅接受纯文本格式的ldap服务器密码。当前的任务是传递一个加密密码,该密码在其初始化阶段被插件使用之前已解密。
我已经搜索了所有可能的博客和stackoverflow问题,但是找不到扩展主插件类以简单地覆盖doWithSpring()方法的方法,这样我就可以为Ldap服务器密码简单地添加所需的解密逻辑。在这里的任何帮助将不胜感激。
我已经看过并尝试过jasypt插件,但是如果密码存储在某个外部文件中而不是应用程序yml中,它也不能很好地工作。因此,我正在寻找一种扩展Spring安全性插件主类,添加所需行为并注册自定义类的解决方案。
编辑
从Grails LDAP安全性插件添加片段,我正在尝试覆盖它。因此,如果我能够在插件加载之前成功更新securityConfig对象的值,则可以解决此目的。
插件的一些代码片段:
def conf = SpringSecurityUtils.securityConfig
...
...
contextSource(DefaultSpringSecurityContextSource, conf.ldap.context.server) { // 'ldap://localhost:389'
authenticationSource = ref('ldapAuthenticationSource')
authenticationStrategy = ref('authenticationStrategy')
userDn = conf.ldap.context.managerDn // 'cn=admin,dc=example,dc=com'
**password = conf.ldap.context.managerPassword // 'secret'**
contextFactory = contextFactoryClass
dirObjectFactory = dirObjectFactoryClass
baseEnvironmentProperties = conf.ldap.context.baseEnvironmentProperties // none
cacheEnvironmentProperties = conf.ldap.context.cacheEnvironmentProperties // true
anonymousReadOnly = conf.ldap.context.anonymousReadOnly // false
referral = conf.ldap.context.referral // null
}
ldapAuthenticationSource(SimpleAuthenticationSource) {
principal = conf.ldap.context.managerDn // 'cn=admin,dc=example,dc=com'
**credentials = conf.ldap.context.managerPassword // 'secret'**
}
最佳答案
您无需在现有插件中覆盖doWithSpring()
方法。您可以提供自己的插件,该插件会在您要影响的插件之后加载,并让doWithSpring()
向上下文添加所需的任何内容。如果您添加与另一个插件添加的名称相同的bean,只要您将插件配置为在另一个插件之后加载,您的 bean 将替换另一个插件提供的bean。同样,如果您不想为此编写插件,则可以在应用程序的resources.groovy
中进行相同的考虑。
您还有其他选择。您可以编写一个影响其他插件创建的bean的bean后处理器或bean定义后处理器。根据具体情况,这可能是一个更好的主意。
编辑:
在下面看到您的评论之后,我创建了一个简单的示例,该示例显示了如何使用定义后处理器。请参阅https://github.com/jeffbrown/postprocessordemo上的项目。
有趣的地方:
https://github.com/jeffbrown/postprocessordemo/blob/master/src/main/groovy/demo/SomeBean.groovy
package demo
class SomeBean {
String someValue
}
https://github.com/jeffbrown/postprocessordemo/blob/master/src/main/groovy/demo/SomePostProcessor.groovy
package demo
import org.springframework.beans.BeansException
import org.springframework.beans.MutablePropertyValues
import org.springframework.beans.PropertyValue
import org.springframework.beans.factory.config.BeanDefinition
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.beans.factory.support.BeanDefinitionRegistry
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
class SomePostProcessor implements BeanDefinitionRegistryPostProcessor{
@Override
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition definition = registry.getBeanDefinition('someBean')
MutablePropertyValues values = definition.getPropertyValues()
PropertyValue value = values.getPropertyValue('someValue')
def originalValue = value.getValue()
// this is where you could do your decrypting...
values.addPropertyValue('someValue', "MODIFIED: ${originalValue}".toString())
}
@Override
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
https://github.com/jeffbrown/postprocessordemo/blob/master/grails-app/conf/spring/resources.groovy
beans = {
someBean(demo.SomeBean) {
someValue = 'Some Value'
}
somePostProcessor demo.SomePostProcessor
}
https://github.com/jeffbrown/postprocessordemo/blob/master/grails-app/init/postprocessordemo/BootStrap.groovy
package postprocessordemo
import demo.SomeBean
class BootStrap {
SomeBean someBean
def init = { servletContext ->
log.info "The Value: ${someBean.someValue}"
}
def destroy = {
}
}
在应用程序启动时,您将看到类似于以下内容的日志输出...
2017-10-23 19:04:54.356 INFO --- [ main] postprocessordemo.BootStrap : The Value: MODIFIED: Some Value
“MODIFIED”有证据表明bean定义后处理器修改了bean中的属性值。在我的示例中,我只是在字符串前面添加了一些文本。在您的实现中,您可以解密密码或在此处执行任何操作。
希望对您有所帮助。
关于grails - 如何自定义现有Grails插件功能,修改doWithSpring方法的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46899705/