2012-05-07 34 views
10

Mam skonfigurowane zabezpieczenie wiosenne za pomocą serwera LDAP (ale kontynuuj czytanie, to nie jest problem, jeśli nie masz o tym wiedzy, to jest naprawdę problem z wiosną). Wszystko działa jak urok. Oto wiersz używam do tego:Wiosna, plik właściwości, puste wartości

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

Gdybym wypełnić LDIF i korzeń atrybuty, to będzie działać serwer osadzone:

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

Gdybym wypełnić pozostałe pola, będzie uruchomić serwer odległy :

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

Wszystko to działa poprawnie. Teraz chcę wykorzystać mechanizm sprężynowy do ładowania takich parametrów z pliku właściwość:

Więc mogę wymienić wartości atrybutów tak:

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

i utworzyć plik działce z:

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

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

Teraz , śmieszna część problemu. Jeśli zapełniam następujące właściwości w pliku:

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= 

Działa na odległym serwerze zgodnie z oczekiwaniami.

Gdybym wypełnić plik własności takiego:

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

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

To nie działa, skarżąc się, że adres URL LDAP brakuje. Ale problemem jest to, że w przypadku zmiany konfiguracji sprężyny z:

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

do (tylko przez usunięcie odniesienia do zmiennej $ {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" /> 

To działa!

Moje jednak są takie, że wiosna nie zastępuje wartości atrybutu właściwością config jeden, jeśli ta jest pusta. Ale uważam to za dziwne.

Czy możesz mi dać jakąś wskazówkę, aby to zrozumieć? A co najlepiej zrobić, aby skonfigurować serwer LDAP za pomocą pliku właściwości?

EDIT: jest to spowodowane złym wyborem projektu (patrzeć na przyjętą odpowiedź), to problem został otwarty na JIRA: https://jira.springsource.org/browse/SEC-1966

+0

Jaka wersja Wiosna używacie? – Roadrunner

+0

To jest 3.0.5.RELEASE –

Odpowiedz

2

OK, myślę, że jest to błąd bezpieczeństwa wiosny.

Jeśli debuguję i przyjrzę się klasie LdapServerBeanDefinition, istnieje metoda o nazwie "parsowanie". Oto fragment:

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

    ... 
} 

Jeśli debugować tutaj, wszystkie zmienne (URL, managerDn, managerPassword ...) nie są zastępowane przez wartości określonej w pliku właściwości. I tak, URL ma wartość $ {ldap.server.url}, managerDn ma wartość $ {ldap.server.manager.dn} i tak dalej.

Analiza metody tworzy komponent bean, źródło kontekstu, które będzie używane dalej. A kiedy ta fasola zostanie użyta, miejsce zostanie zastąpione.

Tutaj mamy błąd. Metoda parsowania sprawdza, czy adres URL jest pusty, czy nie. Problem polega na tym, że adres URL nie jest tutaj pusty, ponieważ ma wartość $ {ldap.server.url}. Tak więc metoda parsowania tworzy źródło kontekstu jako serwer odległy.

Po utworzeniu źródła zostanie zastąpione $ {ldap.server.url} pustą wartością (jak określono w pliku właściwości). I ....... Bug!

nie wiem naprawdę jak rozwiązać ten problem w tej chwili, ale teraz rozumiem, dlaczego błędy;)

+0

To nie jest błąd. Atrybutu url nie należy używać, jeśli zamierzasz utworzyć serwer osadzony. Zobacz http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ldap.html#ldap-server – Ritesh

+0

To, co nazywam błędem, polega na tym, że używanie pustego łańcucha działa i używa zmiennej nie działa, ponieważ kontrola bezpieczeństwa wiosennego nie jest pusta, ponieważ nie zastępuje zmiennej przez jej wartość (która może być pusta!). To kiepski projekt. –

+1

W takim przypadku wydaje mi się, że warto zgłosić problem w narzędziu do śledzenia błędów wiosennych, prawda? https://jira.springsource.org/secure/Dashboard.jspa –

1

Nie mogę tego wyjaśnić, ale myślę, że można rozwiązać problem używając domyślnej składni, dostępnej od wiosny 3.0.0.RC1 (see).

W chageg dziennika można przeczytać: PropertyPlaceholderConfigurer obsługuje „$ {MyKey: myDefaultValue}” składnia zalegających

Zresztą, myślę, że problem jest z powodu „” jest ważna wartość, ale żadna z wartości w pliku właściwości nie rób tego.

+0

dzięki za odpowiedź, ale zawsze mam ten sam błąd, używając domyślnej wskazówki wartości. –

+0

Nie rozumiem tego. Jeśli domyślną wartością jest "" Myślę, że powinno być takie samo, jak ustawienie na "". – jddsantaella

+0

Tak, ja też myślałem ... To bardzo dziwne ... Być może ustawiacz adresu URL jest wywoływany tylko wtedy, gdy używamy wyrażenia wiosennego, a wywołanie settera z pustą wartością powoduje błąd. W przypadku braku określenia wyrażenia, setter może nie jest wywoływany? –

1

myślę że url="" działa, ponieważ atrybut url jest typu xs:token w XSD sprężyną bezpieczeństwa i pusty ciąg jest konwertowany do null (xs:token usuwa żadnych spacji początkowych lub końcowych, tak "" można uznać za bez wartości). Może wartość ${ldap.server.url} jest rozwiązana jako pusty ciąg znaków i dlatego wystąpił błąd.

Można spróbować profili użycie wiosny do definiowania różnych konfiguracji serwera LDAP (patrz Spring Team Blog Szczegółowe informacje na temat profili)

+1

LdapServerBeanDefinitionParser już to robi. W jakiś sposób udało się utworzyć definicję komponentu bean org.springframework.security.ldap.DefaultSpringSecurityContextSource z pustym adresem URL w konstruktorze, mimo że wszystkie kontrole wydają się być na miejscu, aby temu zapobiec. – Ritesh

+1

Myślę, że znalazłem dlaczego Ritesh ma rację i dlaczego nie działa: Kiedy debuguję uruchomienie serwera (w metodzie metody LdapServerBeanDefinition), wszystkie symbole zastępcze nie są zastępowane. Zatem adres URL to: $ {ldap.server.url}. Rozdzielczość właściciela miejsca jest wykonywana po utworzeniu źródła kontekstu. –

+0

Zgodnie z dokumentacją http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ldap.html#ldap-server, atrybut url nie powinien być używany w ogóle, jeśli chcemy utwórz wbudowany serwer. – Ritesh

1

Wierzę, że jest to problem tutaj podczas korzystania posiadaczy miejsce. Poniższa najprawdopodobniej rozwiąże problem:

Tworzenie klasy, która rozciąga PropertyPlaceHolderConfigurer i zastąpić swoją metodę convertPropertyValue() w metodzie można przywrócić nieruchomość jako pusty ciąg, jeśli znajdziesz coś innego niż ciąg znaków, który jest typu URL LDAP, tj. Ldap: //myldapserver.com/dc=springframeworg,dc=org

Musisz również skonfigurować nową specjalizację klasy PropertyPlaceHolderConfigurer w pliku kontekstowym.

Mam nadzieję, że to pomoże.

Powiązane problemy