I have implemented my own LowerCaseUsernamePasswordAuthenticationFilter
that is just a subclass of UsernamePasswordAuthenticationFilter
.
But now my problem is, how to configure Spring security to use this filter.
Up to now I used:
<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>
Do I really to turn of auto-config
and need to configure all the filters by hand? - If this is true, does any开发者_如何学Gobody can provide an example please?
The way to add simply a 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>
does result in an exception with that message:
Configuration problem: Filter beans
<lowerCaseUsernamePasswordAuthenticationFilter>
and 'Root bean: class [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null' have the same 'order' value. When using custom filters, please make sure the positions do not conflict with default filters. Alternatively you can disable the default filters by removing the corresponding child elements from and avoiding the use of .
I have done it by writing the needed autoconfigured beans by hand. This is the result:
<!-- 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>
Here is an example in Scala. I had to do this to replace a filter provided by Spring Security OAuth.
Basically the idea is, inject the FilterChainProxy
and the existing filter that you want to replace into your filter. Find the existing filter in the filterChainMap
and replace it with yours.
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)
}
}
精彩评论