Настройте Spring Security для использования пользовательского UsernamePasswordAuthenticationFilter

Я выполнил свою собственную LowerCaseUsernamePasswordAuthenticationFilter, что это просто подкласс UsernamePasswordAuthenticationFilter.

Но теперь моя проблема заключается в том, как настроить Spring security для использования этого фильтра.

До сих пор я использовал:

<security:http auto-config="true" use-expressions="true">
    <security:form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
    <security:logout logout-url="/resources/j_spring_security_logout" />

    <security:intercept-url pattern="/**" access="isAuthenticated()" requires-channel="${cfma.security.channel}" />
</security:http>

Действительно ли я хочу включить auto-config и настроить все фильтры вручную? - Если это правда, может ли кто-нибудь подать пример, пожалуйста?


Способ добавления просто security:custom-filter:

<security:http ...>

   <security:form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
   <security:custom-filter ref="lowerCaseUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
   ...
 </security:http>

приводит к исключению из этого сообщения:

Проблема с конфигурацией: Фильтрующие компоненты <lowerCaseUsernamePasswordAuthenticationFilter> и "Корневой компонент: класс [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter]; Объем =; абстрактные = ложь; lazyInit = ложь; autowireMode = 0; dependencyCheck = 0; autowireCandidate = TRUE; первичные = ложь; factoryBeanName = NULL; factoryMethodName = NULL; initMethodName = NULL; destroyMethodName = null 'имеют одинаковое значение "порядок". При использовании пользовательских фильтров убедитесь, что позиции не конфликтуют с фильтрами по умолчанию. Кроме того, вы можете отключить фильтры по умолчанию, удалив из него соответствующие дочерние элементы и избегая их использования.

Ответ 1

Я сделал это, написав необходимые автоконфигурированные бобы вручную. Это результат:

<!-- HTTP security configurations -->
<security:http auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">

    <!--
    <security:form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
        replaced by lowerCaseUsernamePasswordAuthenticationFilter
        the custom-filter with position FORM_LOGIN_FILTER requries that auto-config is false!
     -->
    <security:custom-filter ref="lowerCaseUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
    <security:logout logout-url="/resources/j_spring_security_logout" />

    <security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>

<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <property name="loginFormUrl" value="/login"/>
</bean>

<bean id="lowerCaseUsernamePasswordAuthenticationFilter"
    class="com.queomedia.cfma.infrastructure.security.LowerCaseUsernamePasswordAuthenticationFilter">
    <property name="filterProcessesUrl" value="/resources/j_spring_security_check"/>
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="authenticationFailureHandler">
        <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
            <property name="defaultFailureUrl" value="/login?login_error=t"/>       
        </bean>
    </property>
</bean>

Ответ 2

Вот пример в Scala. Я должен был сделать это, чтобы заменить фильтр, предоставленный Spring Security OAuth.

По сути, идея заключается в том, чтобы FilterChainProxy и существующий фильтр, который вы хотите заменить в своем фильтре. Найдите существующий фильтр в filterChainMap и замените его на свой.

import org.springframework.security.oauth2.provider.verification.{VerificationCodeFilter => SpringVerificationCodeFilter}

@Component
class VerificationCodeFilter extends SpringVerificationCodeFilter with InitializingBean {
  @Autowired var filterChainProxy: FilterChainProxy = _
  @Autowired var springVerificationCodeFilter: SpringVerificationCodeFilter = _


  override def afterPropertiesSet() {
    super.afterPropertiesSet()

    val filterChainMap = filterChainProxy.getFilterChainMap
    val filterChain = 
       filterChainMap.find(_._2.exists(_.isInstanceOf[SpringVerificationCodeFilter])).
          getOrElse(throw new Exception("Could not find VerificationCodeFilter in FilterChainMap"))._2
    val index = filterChain.indexOf(springVerificationCodeFilter)
    filterChain.remove(index)
    filterChain.add(index, this)
  }
}