Spring Security Preauth фильтры = ни один не работает

странный,

Я использую Spring Security с siteminder, и он отлично работает. Однако я хочу иметь один незащищенный URL-адрес — нашему loadBalancer нужен URL-адрес «healthCheck» в самом приложении. Этот URL-адрес не перехватывается siteminder, но Spring Security, похоже, все равно применяет к нему предварительную аутентификацию.

если я запускаю его локально, используя простую конфигурацию безопасности на основе форм, работает следующее (исключая фильтры):

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/html/healthCheck.html" filters="none" />   
    <intercept-url pattern="/css/**" filters="none" />
    <intercept-url pattern="/images/**" filters="none" />
    <intercept-url pattern="/js/**" filters="none" />
    <intercept-url pattern="/login" filters="none" />
    <intercept-url pattern="/favicon.ico" filters="none" />
    <intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
    <form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
    <logout logout-success-url="/logout" />
</http>

В этом случае я могу перейти к localhost/myApp/resources/html/healthCheck.html, не сталкиваясь с проблемой авторизации, но любой другой URL-адрес будет отображать форму входа. Пока все выглядит хорошо!

Однако при развертывании на сервере я использую следующую конфигурацию:

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/html/healthCheck.html" filters="none" />   
    <intercept-url pattern="/css/**" filters="none" />
    <intercept-url pattern="/images/**" filters="none" />
    <intercept-url pattern="/js/**" filters="none" />
    <intercept-url pattern="/login" filters="none" />
    <intercept-url pattern="/favicon.ico" filters="none" />
    <intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
    <custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</http>

Когда я перехожу к: server/myapp/resources/html/healthCheck.html, я получаю следующую ошибку:

java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
    org.springframework.security.core.userdetails.User.<init>(User.java:94)
    com.myApp.security.SecuritySBSUserDetailsService.loadUserByUsername(SecuritySBSUserDetailsService.java:119)
    org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:53)

Я думаю, что это вызвано созданием экземпляра UserDetailsService без какого-либо SM_USER. Тем не менее, фильтры = нет ... и работает при использовании проверки подлинности с помощью форм. Есть идеи, что может быть причиной этого, или, что еще лучше, обходной путь?

Кстати, мой сервис userdetails настроен следующим образом:

<beans:bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <beans:property name="principalRequestHeader" value="SM_USER" />
    <beans:property name="exceptionIfHeaderMissing" value="false" />
    <beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

то есть я установил для exceptionIfHeaderMissing значение false, если это помогает..


person Mark D    schedule 16.05.2012    source источник


Ответы (2)


Самое очевидное, что я вижу, это то, что /resources/html/healthCheck.html не будет соответствовать /html/healthCheck.html. Если вы где-то переписываете URL-адреса, вам, вероятно, следует объяснить это.

Если вы включите ведение журнала отладки, оно должно подробно объяснить, что с чем сопоставляется.

Я бы также исключил auto-config. Это вызывает больше путаницы, чем того стоит. И вы должны использовать /**, а не /* для универсального соответствия шаблону муравья.

Вероятно, здесь также стоит упомянуть, что В Spring Security 3.1 реализован лучший подход к определению пустых цепочек фильтров, а также вы можете определить более одной цепочки фильтров, используя синтаксис <http>.

person Shaun the Sheep    schedule 16.05.2012

Хорошо, насколько я вижу, это ошибка в весенней безопасности. Я обошел это, добавив фиктивный возврат в начало метода loadUserByName в UserDetailsService..

@Override
public UserDetails loadUserByUsername(String userName)
        throws UsernameNotFoundException, DataAccessException {
    logger.trace(">> loadUserByUsername()");
    logger.info("-- loadUserByUsername(): username : {}", userName);

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();             
    if(userName==null || userName.trim().equals("")) {
        return(new User("ANONYMOUS", "", true, true, true, true, authorities));
        }
// rest of auth checks

Казалось бы, с имеющейся у меня конфигурацией проверка UserDetails вообще не должна срабатывать (как и с формами ..). Если у кого-то есть обходной путь на основе конфигурации, я дам вам плюс :-)

person Mark D    schedule 16.05.2012
comment
Из информации в вашем вопросе кажется, что вы используете несоответствующий путь. Нет никаких признаков ошибки. Многие люди используют эту конструкцию, поэтому также маловероятно, что что-то настолько очевидное не было бы обнаружено раньше. - person Shaun the Sheep; 01.06.2012