Как использовать J2eePreAuthenticatedProcessingFilter и пользовательский поставщик аутентификации? - PullRequest
5 голосов
/ 23 марта 2012

Я хочу, чтобы мое приложение Spring попробовало два метода предварительной аутентификации ( Siteminder и Аутентификация контейнера Java EE ).

  1. Если какой-либо из этих фильтров находит имя пользователя - я хочу проверить это имя пользователя в моей базе данных пользователей и назначить роли на основе того, что я вижу в базе данных. (У меня есть реализация AuthenticationUserDetailsService, которая делает это для меня.)
  2. Если нет - показать пользователю страницу входа. Проверьте учетные данные, которые они вводят в форме, в моей базе данных пользователей.

Интеграция с Siteminder работает. Форма входа тоже работает. Моя проблема связана с предварительной аутентификацией Java EE. Это никогда не сработает.

Мое приложениеContext-security.xml:

<!-- HTTP security configurations -->
<sec:http auto-config="true" use-expressions="true">
    <sec:form-login login-processing-url="/resources/j_spring_security_check" always-use-default-target="true" default-target-url="/" login-page="/login"
        authentication-failure-url="/login?login_error=t" />
    <sec:logout logout-url="/resources/j_spring_security_logout" />
    <sec:access-denied-handler error-page="/accessDenied" />
    <sec:remember-me user-service-ref="customUserDetailsService" token-validity-seconds="86400" key="OptiVLM-VaultBalance" />
    <sec:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter"/>
    <sec:custom-filter after="PRE_AUTH_FILTER" ref="jeePreAuthenticatedFilter"/>

    <!-- various intercept-url elements here, skipped for brevity -->
</sec:http>

<!-- Authentication Manager -->
<sec:authentication-manager alias="authenticationManager">
    <!-- J2EE container pre-authentication or Siteminder -->
    <sec:authentication-provider ref="customPreAuthenticatedAuthenticationProvider" />
    <!-- Default provider -->
    <sec:authentication-provider user-service-ref="customUserDetailsService" />
</sec:authentication-manager>

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

<!-- J2EE pre-authentication -->
<bean id="jeePreAuthenticatedFilter" class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<!-- Custom pre-authentication provider -->
<bean id="customPreAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService" ref="customAuthenticationUserDetailsService" />
</bean>

У меня включена защита Java 2 в Websphere, и я вошел в систему как 'admin5'. (У меня есть пользователь с этим именем в моей пользовательской базе данных.) Но когда я обращаюсь к приложению, никогда не вызывается bean-компонент customAuthenticationUserDetailsService для проверки имени пользователя. Я знаю это, потому что «customAuthenticationUserDetailsService» ведет обширную регистрацию, которая ясно показывает, что он делает. Когда я использую предварительную аутентификацию Siteminder - 'customAuthenticationUserDetailsService' работает просто отлично, я получаю некоторые результаты трассировки в журнале. Но не для аутентификации J2EE ...

Я предполагаю, что происходит одна из следующих вещей:

a) Фильтр предварительной аутентификации Java EE не находит имя пользователя, поэтому он никогда не вызывает диспетчер аутентификации

b) Фильтр предварительной аутентификации Java EE работает нормально, но мой поставщик аутентификации по какой-либо причине никогда не вызывается менеджером аутентификации

Между прочим, поставщик аутентификации по умолчанию, который использует 'customUserDetailsService', также не включается. Опять же, я могу сказать это, потому что в журнале нет вывода 'customUserDetailsService'.

Можете ли вы посоветовать, в чем здесь проблема? Если бы не решение, то предложение о том, как подойти к этому, будет с благодарностью.

1 Ответ

4 голосов
/ 24 марта 2012

ОК, я понял это. Проблема в том, что, несмотря на то, что у меня была настройка безопасности J2EE в Websphere и я прошел аутентификацию, мой web.xml содержал без ограничений безопасности . Из-за этого Websphere не предоставлял принципала для моих запросов. Это очевидно преднамеренная особенность. Если у вас нет доступа к защищенному URL-адресу, вам не нужна информация о предварительной аутентификации.

Чтобы преодолеть это, я добавил ограничение безопасности в мой web.xml, что позволило ВСЕМ пользователям получить доступ к ресурсам. По сути, ресурсы не были обеспечены, но все же - теперь было ограничение.

Вот оно:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>All areas</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
</security-constraint>

Это обманывает Websphere при заполнении основной информации пользователя в запросе.

Спасибо @Ralph за комментарии к этому вопросу: request.getUserPrincipal () получил значение null

...