第 43 章 自定义过滤器

常见的问题就是要在登录时多加几个参数时,默认的AuthenticationProcessFilter既不支持保存额外参数,也没有提供扩展点来实现这个功能,实际上就算是Spring Security-3.x中也因为只能配置一个handler,实际扩展时还是比较麻烦。所以这个时候一般的选择就是自定义过滤器了。

我们的目标是在登录时除了填写用户名和密码之外,再添加一个mark参数。

登录时附加一个mark参数

图 43.1. 登录时附加一个mark参数


我们的目的是在登录时将这个参数保存到session中,以备后用。为此我们要扩展AuthenticationProcessFilter:

public class LoginFilter extends UsernamePasswordAuthenticationFilter {
    public Authentication attemptAuthentication(
        HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException {
        Authentication authentication = super
            .attemptAuthentication(request, response);

        String mark = request.getParameter("mark");
        request.getSession().setAttribute("mark", "mark");

        return authentication;
    }
}
    

实际上我们只需要重写attemptAuthentication()这个方法,先调用super.attemptAuthentication()获得生成的Authentication,如果这部分没有抛出异常,我们下面再去从request中获得mark参数,再把这个参数保存到session里。最后返回authentication对象即可。

下面修改配置文件,在xml中添加一个名为loginFilter的bean,使用custom-filter将它加入到过滤器链中,放到原来的form-login的前面。

<http auto-config='true'>
	<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
	<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
	<intercept-url pattern="/**" access="ROLE_USER" />
	<form-login login-page="/login.jsp"
				authentication-failure-url="/login.jsp?error=true"
				default-target-url="/" />
	<custom-filter before="FORM_LOGIN_FILTER" ref="loginFilter" />
</http>

<beans:bean id="loginFilter" class="com.family168.springsecuritybook.ch211.LoginFilter">
	<beans:property name="authenticationManager" ref="org.springframework.security.authenticationManager"/>
</beans:bean>
    

这样我们自定义的LoginFilter就会取代原本的AuthenticationProcessFilter处理用户登录,并在用户登录成功时将额外的mark参数保存到session中。

之后在jsp中,我们就可以直接通过${sessionScope['mark']}来获得mark的参数值。

显示额外的参数

图 43.2. 显示额外的参数


实例在ch211中。