将 Spring Security 配置为使用自定义 UsernamePasswordAuthenticationFilter

2022-09-04 02:54:54

我已经实现了我自己的,它只是的一个子类。LowerCaseUsernamePasswordAuthenticationFilterUsernamePasswordAuthenticationFilter

但现在我的问题是,如何配置Spring安全性以使用此过滤器。

到目前为止,我使用:

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

确实会导致该消息异常:

配置问题:Filter bean 和 'Root bean: class [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter];范围 =;抽象=假;lazyInit=false;自动线模式 = 0;依赖性检查= 0;自动线候选 = 真;主要 = 假;factoryBeanName=null;工厂方法名称 =空;initMethodName=null;destroyMethodName=null' 具有相同的“order”值。使用自定义过滤器时,请确保位置不与默认过滤器冲突。或者,您可以通过从 中删除相应的子元素并避免使用 来禁用默认筛选器。<lowerCaseUsernamePasswordAuthenticationFilter>


答案 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提供的过滤器。

基本上,我们的想法是,将要替换的现有过滤器注入到过滤器中。在 中找到现有筛选器,并将其替换为您的筛选器。FilterChainProxyfilterChainMap

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

推荐