一个赛事记分项目是个单体应用,包括后台管理和普通参赛人员两种角色。显然,后台管理人员是固定的,而参赛人员每个赛事是不一样的,要求后台管理人员和参赛人员都可以登录系统并操作不同的功能。
很明显这是两种角色,每种角色需要使用不同的登录方式,而且每个角色的用户保存在不同的表中。其中管理员使用用户名密码登录,参赛人员使用队员配对登录方式。
系统使用spring-security作为安全框架,但是把login写到controller里,而非使用UsernamePasswordAuthenticationFilter。为了拦截UsernamePasswordAuthenticationFilter,在它前面添加了自定义Filter
。在自定义Filter中实现获取用户信息功能。在配置类中配置AuthenticationManager,支持多个验证provider。
在登录controller中分别实现两个登录接口,通过创建不同的AbstractAuthenticationToken实现类,spring-security框架自动找到相关的AuthenticationProvider并调用验证方法authenticate。
其中supports方法用来选择支持相应AbstractAuthenticationToken的AuthenticationProvider。
总体流程是:登录接口调用登录方法->登录方法创建对应AbstractAuthenticationToken实现类,并调用AuthenticationManager.authenticate方法->AuthenticationManager根据token类型找到AuthenticationProvider->调用AuthenticationProvider.authenticate方法执行用户验证。