Spring Security 自己的UsernamePasswordAuthenticationFilter 只支持 帐号与密码的验证,若是须要加入诸如验证码等其它条件时,能够经过继承UsernamePasswordAuthenticationFilter 并重写其中的方法 attemptAuthentication来实现。java
java代码以下web
public class ValidateCodeFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(final HttpServletRequest request, final HttpServletResponse response) throws AuthenticationException { String validateCode = request.getParameter("validateCode"); if (validateCode == null) { validateCode = ""; } final String validation_code = (String) request.getSession().getAttribute("validation_code"); logger.info("开始校验验证码,生成的验证码为:" + validation_code + " ,输入的验证码为:" + validateCode); if (!validateCode.equals(validation_code)) { throw new LockedException("text.login.username.notexist"); } return super.attemptAuthentication(request, response); } }
spring-security-config.xml 配置以下spring
<!-- validate filter --> <bean id="validateFilter" class="com.java.filters.ValidateCodeFilter"> <property name="authenticationManager" ref="authenticationManager"></property> <property name="authenticationSuccessHandler" ref="loginAuthenticationSuccessHandler"> </property> <property name="authenticationFailureHandler" ref="loginAuthenticationFailureHandler"> </property> </bean>
<!-- Default security config --> <security:http request-matcher-ref="excludeUrlRequestMatcher" entry-point-ref="loginEntryPoint" auto-config="false"> <security:anonymous username="anonymous" granted-authority="ROLE_ANONYMOUS" /> <security:access-denied-handler error-page="/login"/> <security:session-management session-authentication-strategy-ref="fixation" /> <security:csrf token-repository-ref="csrfTokenRepository" request-matcher-ref="csrfProtectionMatcher" /> <security:custom-filter before="CSRF_FILTER" ref="logoutFilter" /> <!-- 替代原生的验证 --> <security:custom-filter position="FORM_LOGIN_FILTER" ref="customLoginFilter" /> <!-- RememberMe --> <security:remember-me key="jahwastorefront" services-ref="rememberMeServices" /> <!-- SSL / AUTHENTICATED pages --> <security:intercept-url pattern="/my-account/addressform" access="hasAnyRole('ROLE_ANONYMOUS','ROLE_CUSTOMERGROUP')" requires-channel="https" /> <security:intercept-url pattern="/checkout/multi/billingaddressform" access="hasAnyRole('ROLE_ANONYMOUS','ROLE_CUSTOMERGROUP')" requires-channel="https" /> <security:intercept-url pattern="/my-account*" access="hasRole('ROLE_CUSTOMERGROUP')" requires-channel="https" /> <security:intercept-url pattern="/my-account/order/*/getReadOnlyProductVariantMatrix" access="hasAnyRole('ROLE_ANONYMOUS','ROLE_CUSTOMERGROUP')" requires-channel="https" /> <security:intercept-url pattern="/my-account/**" access="hasRole('ROLE_CUSTOMERGROUP')" requires-channel="https" /> <security:intercept-url pattern="/quote/**" access="hasRole('ROLE_CUSTOMERGROUP')" requires-channel="https" /> <security:intercept-url pattern="/**" requires-channel="https" /> <!-- Everything should be secure --> <!-- 这个地方必定要注释掉 <security:form-login login-page="/login" authentication-failure-handler-ref="loginAuthenticationFailureHandler" authentication-success-handler-ref="loginGuidAuthenticationSuccessHandler" username-parameter="j_username" password-parameter="j_password" login-processing-url="/j_spring_security_check" /> -->
<!-- loginEntryPoint --> <bean id="loginEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <!-- 默认登陆页的url --> <constructor-arg value="/login" /> </bean>
另一定要注意 配置 auto-config="false",否则会报以下的错误session
nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Filter beans '<validateFilter>' and '<org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0>' 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 <http> and avoiding the use of <http auto-config='true'>.