10

LDAP サーバーを使用してスプリング セキュリティを構成しました (ただし、読み続けてください。知識がなくても問題ありません。これは実際にはスプリングの問題です)。すべてが魅力のように実行されます。これが私がそのために使用する行です:

<ldap-server ldif="" root="" manager-dn="" manager-password="" url=""  id="ldapServer" />

ldif および root 属性を入力すると、組み込みサーバーが実行されます。

<ldap-server ldif="classpath://ldap.ldif" root="dc=springframework,dc=org" manager-dn="" manager-password="" url=""  id="ldapServer" />

他のフィールドに入力すると、遠隔サーバーが実行されます。

<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" />

これらはすべて正しく実行されます。次に、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" />

プロパティ ファイルを次のように作成します。

ldap.server.url=
ldap.server.manager.dn=
ldap.server.manager.password=

ldap.ldif.path= 
ldap.ldif.root= 

さて、問題の面白い部分です。ファイルに次のプロパティを入力すると:

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= 

期待どおりに遠隔サーバーを実行します。

プロパティ ファイルを次のように入力すると、次のようになります。

ldap.server.url=
ldap.server.manager.dn=
ldap.server.manager.password=

ldap.ldif.path= classpath:ldap.ldif
ldap.ldif.root= dc=springframeworg,dc=org

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" />

に (変数 ${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" />

走る!

私の考えでは、これが空の場合、春は属性値をプロパティ設定値に置き換えません。しかし、私はそれが奇妙だと思います。

それを理解する手がかりを教えてもらえますか?また、プロパティ ファイルを使用して LDAP サーバーを構成するにはどうすればよいですか?

編集: これは設計の選択が不十分なためです (受け入れられた回答を見てください)。jira で問題が開かれています: https://jira.springsource.org/browse/SEC-1966

4

5 に答える 5

2

わかりました、これは春のセキュリティ バグだと思います。

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);
    }

    ...
}

ここでデバッグすると、すべての変数 (url、managerDn、managerPassword など) がプロパティ ファイルで指定された値に置き換えられません。したがって、url の値は ${ldap.server.url}、managerDn の値は ${ldap.server.manager.dn} などです。

メソッド parse は、さらに使用されるコンテキスト ソースである Bean を作成します。そして、この Bean が使用されると、プレースホルダーが置き換えられます。

ここで、バグが発生しました。parse メソッドは、url が空かどうかをチェックします。問題は、値が ${ldap.server.url} であるため、ここで URL が空でないことです。そのため、parse メソッドはコンテキスト ソースを遠隔サーバーとして作成します。

作成されたソースが使用される場合、${ldap.server.url} は空の値 (プロパティ ファイルで指定されているものなど) に置き換えられます。そして.......バグ!

今のところこれを解決する方法が本当にわかりませんが、なぜバグなのかがわかりました;)

于 2012-05-28T08:02:21.510 に答える
1

説明はできませんが、Spring 3.0.0.RC1以降で使用可能なデフォルトの構文を使用して問題を修正できると思います(を参照)。

変更ログでは、次のように読むことができます。PropertyPlaceholderConfigurerは、「$ {myKey:myDefaultValue}」のデフォルト構文をサポートしています。

とにかく、問題は「」が有効な値であるためだと思いますが、プロパティファイルの値はそうではありません。

于 2012-05-07T17:50:03.757 に答える
1

プレースホルダーの使用中にここに問題があると思います。ほとんどの場合、次の方法で問題を解決できます。

PropertyPlaceHolderConfigurer を拡張するクラスを作成し、メソッドでそのメソッド convertPropertyValue() をオーバーライドします。LDAP url タイプの文字列以外のものが見つかった場合は、プロパティを空の文字列として返すことができます。つまり、ldap://myldapserver.com/dc=springframeworg ,dc=組織

また、コンテキスト ファイルでクラス PropertyPlaceHolderConfigurer の新しい特殊化を構成する必要があります。

お役に立てれば。

于 2012-05-28T07:44:32.320 に答える
1

attribute はspring-security XSD の型であり、空の文字列が(先頭または末尾のスペースを削除しているため、値なしと認識できる) に変換されるため、url=""機能すると思います。の値が空の文字列として解決される可能性があり、それがエラーが発生した理由です。urlxs:tokennullxs:token""${ldap.server.url}

Spring プロファイルを使用して、LDAP サーバーのさまざまな構成を定義することができます (プロファイルの詳細については、 Spring チームのブログを参照してください)。

于 2012-05-25T12:53:52.030 に答える