spring security 4 filter UsernamePasswordAuthenticationFilter(一)

本文探讨了Spring Security框架中的UsernamePasswordAuthenticationFilter过滤器,它主要用于处理表单登录请求。从源码分析,讲解了过滤器的属性、工作流程,包括如何在配置中启用,并详细阐述了AuthenticationManager和AuthenticationProvider的角色,强调了自定义userDetailService在认证过程中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      spring security 就是由一系列filter组成的一个安全认证框架,熟悉其中一些重要的filter是对熟悉spring security本身就是一种方式。首先我将先附上spring security官网上几个默认的filter

然后我会重点讲几个,今天我们先说UsernamePasswordAuthenticationFilter这个过滤器,从官网上的截图可以看到左边的别名是“FORM_LOGIN_FILTER”,最右边的是其namespace element(命名空间)以及 attribute(配置属性),可以看到这个filter显示的是http/form-login。那这filter主要做什么,其实我们从别名和属性可以看主要处理form-login,form表单登录请求处理的filter。这个就体现出其重要性了,毕竟是登录这一块。

         我们先来看一下源码,我们先看一下UsernamePasswordAuthenticationFilter父类AbstractAuthenticationProcessingFilter

public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean implements ApplicationEventPublisherAware, MessageSourceAware {
    protected ApplicationEventPublisher eventPublisher;
    protected AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
    private AuthenticationManager authenticationManager;
    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
    private RememberMeServices rememberMeServices = new NullRememberMeServices();
    private RequestMatcher requiresAuthenticationRequestMatcher;
    private boolean continueChainBeforeSuccessfulAuthentication = false;
    private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();
    private boolean allowSessionCreation = true;
    private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
    private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();

    protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl) {
        this.setFilterProcessesUrl(defaultFilterProcessesUrl);
    }

    protected AbstractAuthenticationProcessingFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
        Assert.notNull(requiresAuthenticationRequestMatcher, "requiresAuthenticationRequestMatcher cannot be null");
        this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
    }

    public void afterPropertiesSet() {
        Assert.notNull(this.authenticationManager, "authenticationManager must be specified");
    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse)res;
         // 判断访问是否需要过滤
        // 默认过滤 /login  post方式
        if (!this.requiresAuthentication(request, response)) {
            chain.doFilter(request, response);
        } else {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Request is to process authentication");
            }

            Authentication authResult;
            try {
                authResult = this.attemptAuthentication(request, response);
                if (authResult == null) {
                    return;
                }

                this.sessionStrategy.onAuthentication(authResult, request, response);
            } catch (InternalAuthenticationServiceException var8) {
                this.logger.error("An internal error occurred while trying to authenticate the user.", var8);
                
### Spring SecurityUsernamePasswordAuthenticationFilter 的使用与配置 #### 配置基础设置 为了使 `UsernamePasswordAuthenticationFilter` 正常工作,在应用程序的安全配置类中需继承 `WebSecurityConfigurerAdapter` 并重写相应方法。通常情况下,当调用 `http.formLogin()` 方法时会自动注册此过滤器[^3]。 ```java @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll(); } } ``` 上述代码片段展示了如何启用表单登录功能并允许匿名访问 `/login` 页面。这将触发默认的 `UsernamePasswordAuthenticationFilter` 进行处理。 #### 定制化 UsernamePasswordAuthenticationFilter 对于更复杂的需求,可以创建自己的 `UsernamePasswordAuthenticationFilter` 实现: 1. 创建个新的 Java 类扩展 `UsernamePasswordAuthenticationFilter`. 2. 覆盖必要的方法如 `attemptAuthentication`. ```java public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final AuthenticationManager authenticationManager; public CustomUsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager){ this.authenticationManager = authenticationManager; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { // 自定义逻辑... return super.attemptAuthentication(request,response); } } ``` 之后需要在安全配置文件里替换默认的过滤器实例为自定义版本: ```java @Override protected void configure(HttpSecurity http) throws Exception { CustomUsernamePasswordAuthenticationFilter customFilter = new CustomUsernamePasswordAuthenticationFilter(authenticationManagerBean()); http.addFilterAt(customFilter, UsernamePasswordAuthenticationFilter.class) ... } ``` 这样就完成了对 `UsernamePasswordAuthenticationFilter` 的个性化调整. #### 处理 POST 请求 URL 登录认证 默认情况下,`UsernamePasswordAuthenticationFilter` 将监听路径模式为 `/login` 的 POST 请求作为提交用户凭证的方式。可以通过修改 `setFilterProcessesUrl(String defaultFilterProcessesUrl)` 来改变这行为[^4]: ```java customFilter.setFilterProcessesUrl("/myCustomLoginPath"); ``` 以上操作使得应用能够响应来自不同URL地址上的登录尝试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值