2017-10-23 16 views
0

私はGrailsを初めて使用していますが、Spring Security LDAPプラグインを使用しているときにldapサーバーのパスワードをプレーンテキストのみで受け入れることが確認されました。現在の課題は、初期化段階でプラグインが消費する前に復号化された暗号化されたパスワードを渡すことです。既存のGrailsプラグインの機能をカスタマイズしてdoWithSpringメソッドの動作を変更する方法

私は既にすべての可能なブログとstackoverflowの質問を検索しましたが、単純にdoWithSpring()メソッドをオーバーライドするようにメインプラグインクラスを拡張する方法を見つけることができなかったので、Ldapサーバーパスワード。ここでの助けに感謝します。

私はすでにjasyptプラグインを見て、試しましたが、パスワードがアプリケーションymlではなく外部ファイルに保存されているとうまく動作しません。だから私はSpringセキュリティプラグインのメインクラスを拡張し、必要な動作を追加し、カスタムクラスを登録するためのソリューションを探しています。

EDIT

私が上書きしようとしていますGrailsのLDAPセキュリティー・プラグインからのスニペットを追加します。したがって、プラグインがロードされる前にsecurityConfigオブジェクトの値を正常に更新できたら、その目的は解決されます。あなたは、既存のプラグインでdoWithSpring()メソッドをオーバーライドする必要はありません

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'** 
    } 

答えて

0

:プラグインから

一部抜粋。影響を受けたいものの後にロードする独自のプラグインを用意して、doWithSpring()にコンテキストに必要なものを追加することができます。他のプラグインで追加されたものと同じ名前のBeanを追加すると、もう一方のプラグインをロードするようにプラグインを設定していれば、他のプラグインによって提供されているものと置き換えられます。同様に、これについてプラグインを書いたくない場合は、同じ考えをアプリケーションのresources.groovyで行うことができます。

他にもオプションがあります。他のプラグインによって作成されたBeanに影響するBeanポストプロセッサーまたはBean定義ポストプロセッサーを記述することができます。詳細に応じて、それは良いアイデアかもしれません。

EDIT:

私はあなたが定義ポストプロセッサを使用する方法を示し、簡単な例を作成したの下にあなたのコメントを見た後。プロジェクトを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

アプリケーション起動時に、次のようなログ出力が表示されます。

2017-10-23 19:04:54.356 INFO --- [   main] postprocessordemo.BootStrap    : The Value: MODIFIED: Some Value 

"MODIFIED"は、Bean定義ポストプロセッサがBeanのプロパティ値を変更したという証拠があります。私の例では、文字列にテキストを単に追加しています。あなたの実装では、パスワードを解読するか、そこで何をしたいかを行うことができます。

私は役立つことを願っています。

+0

ありがとうございますJeff、まずポストプロセッサをお試しください。結果に基づいて元に戻ります。 –

+0

私はこれを試み、BeanPostProcessor内のSpringSecurityUtilsのconfigObjectクラスを取得して変更することができましたが、残念ながら、GrailsPluginsはBeanPostProcessor自体の前に読み込まれて初期化されているようです。 変更されたldapPasswordの値が取得されませんでした。 上記のクエリでgrailsプラグインのスニペットを追加しました。 –

+0

"私はこれを試み、BeanPostProcessor内のSpringSecurityUtilsのconfigObjectクラスを取得して変更することができました。" - それを行うことはお勧めできません。私はbean定義を変更します。 –

0

私のユースケースではJazeptプラグインとBeanPostProcessorソリューションがうまくいっていなかったので、以下の解決策が完全に機能することが分かりました。ここでもう一度、問題文を記述するために

、 a)は、我々は bはファイルのプロパティ内の暗号化された形式でパスワードを続けなければならなかった)とプロパティは、戦争の内側に保持されてはならないので、我々はWARファイルとしてパッケージ化された、指定されました自動配備スクリプトが環境に応じて暗号化されたパスワードを更新できるようにする

Jasyptプラグインはa)のケースでは完璧なソリューションでしたが、b)のシナリオをカバーできませんでした さらに、Grails LDAP Securityプラグインはかなり早くロードされてしまったので、Bean Postプロセッサーもここで助けてくれませんでした。

ソリューション: SpringApplicationRunListenerインターフェイスを実装して新しいクラスを作成しました。そのメソッドを拡張し、特性がYamlPropertySourceLoader

サンプルコードを使用してファイル構文解析:

YamlPropertySourceLoader loader = new YamlPropertySourceLoader(); 
    PropertySource<?> applicationYamlPropertySource = loader.load( 
    "application.yml", new ClassPathResource("application.yml"),"default"); 
    return applicationYamlPropertySource; 

プロパティがMapPropertySourceオブジェクトの内部にロードした後は暗号化された値のためにそれらを解析し、復号化ロジックを適用しました。

この全体の実装は、目的を解決するGrailsの起動プロセス中にプラグインが初期化される前に実行されました。

他人に役立つことを願っています。

関連する問題