本文介绍如何实现用户名加数字签名的方式进行身份认证,顺便分析一下security4框架对身份认证的过程,如果自己要进行业务如何进行扩展。
1.在UsernamePasswordAuthenticationFilter之前添加自定义的filter,并设置该filter拦截的登录认证URL请求,注意身份认证的filter只拦截指定的URL请求,其他URL请求不会拦截,见身份认证基类AbstractAuthenticationProcessingFilter的doFilter方法。
具体的配置信息见springSecurityConfig中的配置代码:
http.addFilterBefore(buildUserSignAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
2.自定义AuthenticationProvider和Authentication的实现类,这两个类的作用就是用于身份认证,具体实现
见UserSignAuthenticationProvider和UserSignAuthenticationToken
3.身份认证的执行过程大致如下,以本案为例:
http://127.0.0.1:8081/security/user_sign?username=admin&sign=123
所有URL请求都会被FilterChainProxy 拦截,执行方法见: FilterChainProxy 调用doFilterInternal拦截处理URL请求
处理步骤大致:
a.获取当前URL请求配置的拦截器
List<Filter> filters = getFilters(fwRequest);
b.判断是否有对应的拦截器,没有则通过
if (filters == null || filters.size() == 0) {chain.doFilter(fwRequest, fwResponse);return;}
c. 有拦截器,则进行拦截处理,该处使用责任链模式处理URL请求,必须所有的拦截器都通过,URL才能正确被访问 VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);vfc.doFilter(fwRequest, fwResponse);
步骤b中的URL配置在springSecurity配置方法configure(WebSecurity web)中,配置中的URL都是静态资源,不需要对应拦截器实现类,
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");
}
步骤c中需要拦截的URL配置在springSecurity配置方法configure(HttpSecurity http)中,默认的表单登录身份认证配置包括登录URL,登录成功跳转url,登录失败跳转url等。
http.formLogin().loginPage("/login").failureForwardUrl("").successForwardUrl("").permitAll();
当需要添加自定义身份认证时,添加过滤器必须添加在默认的表单身份认证之前;因为步骤c处理url是按照List<filter>中的元素顺序进行的。
--------------------------------------------------------------------------------------------------------------------------------
当步骤c拦截到自定义身份认证URL/user_sign?username=admin&sign=123 时,代码执行过程:
UserSignAuthenticationFilter ---> ProviderManager ---> UserSignAuthenticationProvider ;
UserSignAuthenticationFilter 将用户填写信息填入UserSignAuthenticationToken,交给ProviderManager 处理;
UserSignAuthenticationProvider 是身份认证的最终执行者,完成身份认证,通过后会将对应的权限信息补充到UserSignAuthenticationToken中。
ProviderManager 的验证过程由 List<AuthenticationProvider> providers来完成,只要providers有一个AuthenticationProvider验证通过,则身份验证通过,所以一个WEB应用可以同时存在多种身份验证方式。
源码地址:https://gitee.com/json20080301/spring-boot-spring-security-thymeleaf
验证方式:http://127.0.0.1:8081/security/user_sign?username=admin&sign=123