绝活!Spring Security过滤器就该这么配置
以前胖哥带大家用Spring Security过滤器实现了手机验证码认证,绝活今天我们来改良一下验证码认证的过滤配置方式。这绝对是器该绝活666,不再看、配置点赞一波吗?绝活天天白嫖,晚上睡得着觉?过滤
CaptchaAuthenticationFilter这个验证码过滤器是通过模仿UsernamePasswordAuthenticationFilter实现的。同样的器该道理,由于UsernamePasswordAuthenticationFilter的配置配置是由FormLoginConfigurer来完成的,应该也能模仿一下FormLoginConfigurer,绝活写一个配置类CaptchaAuthenticationFilterConfigurer去配置CaptchaAuthenticationFilter。过滤
public final class FormLoginConfigurer
AbstractAuthenticationFilterConfigurer
// 省略
}AbstractAuthenticationFilterConfigurer
FormLoginConfigurer看起来有点复杂,不过继承关系并不复杂,配置只继承了AbstractAuthenticationFilterConfigurer。绝活
public abstract class AbstractAuthenticationFilterConfigurer,过滤 T extends AbstractAuthenticationFilterConfigurer, F extends AbstractAuthenticationProcessingFilter>
extends AbstractHttpConfigurer
理论上我们模仿一下,也继承一下这个类,器该但是你会发现这种方式行不通。因为AbstractAuthenticationFilterConfigurer只能Spring Security内部使用,不建议自定义。原因在于它最终向HttpSecurity添加过滤器使用的是HttpSecurity.addFilter(Filter)方法,这个方法只有内置过滤器(参见FilterOrderRegistration)才能使用。了解了这个机制之后,我们只能往上再抽象一层,网站模板去改造其父类AbstractHttpConfigurer。
改造过程
AbstractAuthenticationFilterConfigurer中的B是实际指的HttpSecurity,因此这个要保留;
T指的是它本身的实现,我们配置CaptchaAuthenticationFilter不需要下沉一层到FormLoginConfigurer这个继承级别,直接在AbstractAuthenticationFilterConfigurer这个继承级别实现即可,因此T这里指的就是需要配置类本身,也不需要再抽象化,因此是不需要的;同样的原因F也不需要,很明确是CaptchaAuthenticationFilter,不需要再泛化。这样CaptchaAuthenticationFilter的配置类结构可以这样定义:
public class CaptchaAuthenticationFilterConfigurer // 不再泛化 具体化  private final CaptchaAuthenticationFilter authFilter; // 特定的验证码用户服务 private CaptchaUserDetailsService captchaUserDetailsService; // 验证码处理服务 private CaptchaService captchaService; // 保存认证请求细节的策略  private AuthenticationDetailsSource // 默认使用保存请求认证成功处理器  private SavedRequestAwareAuthenticationSuccessHandler defaultSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler(); // 认证成功处理器 private AuthenticationSuccessHandler successHandler = this.defaultSuccessHandler; // 登录认证端点 private LoginUrlAuthenticationEntryPoint authenticationEntryPoint; // 是否 自定义页面  private boolean customLoginPage; // 登录页面 private String loginPage; // 登录成功url private String loginProcessingUrl; // 认证失败处理器 private AuthenticationFailureHandler failureHandler; // 认证路径是否放开 private boolean permitAll; // 认证失败的url private String failureUrl; / * Creates a new instance with minimal defaults */ public CaptchaAuthenticationFilterConfigurer() { setLoginPage("/login/captcha"); this.authFilter = new CaptchaAuthenticationFilter(); } public CaptchaAuthenticationFilterConfigurer this.formLoginEnabled = false; return this; } public CaptchaAuthenticationFilterConfigurer this.captchaUserDetailsService = captchaUserDetailsService; return this; } public CaptchaAuthenticationFilterConfigurer this.captchaService = captchaService; return this; } public CaptchaAuthenticationFilterConfigurer authFilter.setUsernameParameter(usernameParameter); return this; } public CaptchaAuthenticationFilterConfigurer authFilter.setCaptchaParameter(captchaParameter); return this; } public CaptchaAuthenticationFilterConfigurer authFilter.setConverter(converter); return this; } @Override public void init(H http) throws Exception { updateAuthenticationDefaults(); updateAccessDefaults(http); registerDefaultAuthenticationEntryPoint(http); // 这里禁用默认页面过滤器 如果你想自定义登录页面 可以自行实现 可能和FormLogin冲突 // initDefaultLoginFilter(http); // 把对应的Provider也在init时写入HttpSecurity initProvider(http); } @Override public void configure(H http) throws Exception { //这里改为使用前插过滤器方法 http.addFilterBefore(filter, LogoutFilter.class); } // 其它方法 同AbstractAuthenticationFilterConfigurer 其实就是模仿AbstractAuthenticationFilterConfigurer及其实现类的风格把用的服务器托管配置项实现一遍。这里值得一提的是CaptchaService的配置也可以从Spring            IoC中查找(参考getBeanOrNull方法,这个方法在Spring            Security中随处可见,建议借鉴),这样更加灵活,既能从方法配置也能自动注入。 private void initProvider(H http) { ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class); // 没有配置CaptchaUserDetailsService就去Spring IoC获取 if (captchaUserDetailsService == null) { captchaUserDetailsService = getBeanOrNull(applicationContext, CaptchaUserDetailsService.class); } // 没有配置CaptchaService就去Spring IoC获取 if (captchaService == null) { captchaService = getBeanOrNull(applicationContext, CaptchaService.class); }  // 初始化 Provider CaptchaAuthenticationProvider captchaAuthenticationProvider = this.postProcess(new CaptchaAuthenticationProvider(captchaUserDetailsService, captchaService)); // 会增加到ProviderManager的注册列表中 http.authenticationProvider(captchaAuthenticationProvider); 我们来看看CaptchaAuthenticationFilterConfigurer的配置效果: @Bean SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http, UserDetailsService userDetailsService) throws Exception { http.csrf().disable() .authorizeRequests() .mvcMatchers("/foo/**").access("hasAuthority(ROLE_USER)") .anyRequest().authenticated() .and() // 所有的 AbstractHttpConfigurer 都可以通过apply方法加入HttpSecurity .apply(new CaptchaAuthenticationFilterConfigurer<>()) // 配置验证码处理服务 这里直接true 方便测试 .captchaService((phone, rawCode) -> true) // 通过手机号去拿验证码,这里为了方便直接写死了,实际phone和username做个映射  .captchaUserDetailsService(phone -> userDetailsService.loadUserByUsername("felord")) // 默认认证成功跳转到/路径 这里改造成把认证信息直接返回json .successHandler((request, response, authentication) -> { // 这里把认证信息以JSON形式返回 ServletServerHttpResponse servletServerHttpResponse = new ServletServerHttpResponse(response); MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); mappingJackson2HttpMessageConverter.write(authentication, MediaType.APPLICATION_JSON,servletServerHttpResponse); }); return http.build(); 是不是要优雅很多,解决了你自己配置过滤器的很多疑难杂症。学习一定要模仿,先模仿成功,然后再分析思考为什么会模仿成功,最后形成自己的创造力。千万不要被一些陌生概念唬住,有些改造是不需要去深入了解细节的。 本文转载自微信公众号「码农小胖哥」,可以通过以下二维码关注。转载本文请联系码农小胖哥公众号。         配置类效果

相关文章
Flyme5.1.6.0a(打造独特个性化的手机主题,尽享视觉盛宴)
摘要:在当今智能手机时代,个性化已经成为了用户对手机的一个基本要求。Flyme5.1.6.0a作为一款强大的主题定制平台,不仅为用户提供了海量的主题选择,而且还可以满足用户对手机外观和功...2025-11-04- 复制testdb=#SELECTASCII(2); +---------------------------------------------------------+2025-11-04
 - 复制testdb=#SELECTASCII(2); +---------------------------------------------------------+2025-11-04
 
对于关键基础设施,安全是不可协商的。保护网络、系统和资产以实现不间断运营对于组织、城市和国家的安全至关重要。令人遗憾的是,网络犯罪分子可以渗透 93% 的公司网络 (betanews.com)。鉴于此2025-11-04- 摘要:在日常使用电脑过程中,我们难免会遇到系统崩溃或需要重新安装系统的情况。而制作一个系统U盘,则可以方便我们在这种情况下快速恢复系统或重新安装系统。本文将详细介绍以电脑为工具,如何制作...2025-11-04
 - 复制publicclassMergeJoin { //Assumethatleftandrightarealreadysorted2025-11-04
 

最新评论