跳至主要內容

BasicAuthenticationFilter

Jin大约 2 分钟

BasicAuthenticationFilter

BasicAuthenticationFilter 是一个非常重要的过滤器,负责处理基于 HTTP Basic Authentication 的身份验证。它是 Spring Security 用于支持 "Basic Authentication" 认证方式的核心过滤器之一。通过该过滤器,Spring Security 可以从 HTTP 请求头中提取用户的用户名和密码,并进行身份验证。

1、HTTP Basic Authentication 简介

  • HTTP 基本认证:这是一种简单的认证机制,客户端通过在 HTTP 头部提供一个 Authorization 字段来发送用户名和密码。这个字段的内容是 "Basic" 后跟一个空格和一个 Base64 编码后的字符串,该字符串是用户名和密码拼接而成的,格式为 username:password
  • BasicAuthenticationFilter:它负责拦截所有带有 Authorization 头且类型为 "Basic" 的请求,并尝试从中解析出用户名和密码。如果认证成功,则将用户信息添加到 SecurityContext 中;如果失败,则返回一个 401 (Unauthorized) 响应。

HTTP 请求头示例:

Authorization: Basic <base64-encoded-username:password>

2、配置

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(authorize -> authorize
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .httpBasic(); // 开启 HTTP 基本认证支持
            
        return http.build();
    }
}

在这个例子中,我们首先定义了哪些 URL 路径可以被匿名访问(/public/**),其他所有路径都需要用户通过 HTTP 基本认证来访问。.httpBasic() 方法调用开启了对 HTTP 基本认证的支持。

3、自定义 BasicAuthenticationFilter

如果你需要自定义 BasicAuthenticationFilter 的行为,比如改变认证失败的响应或者添加额外的认证逻辑,你可以创建一个继承自 BasicAuthenticationFilter 的类,并重写相应的方法。例如:

public class CustomBasicAuthenticationFilter extends BasicAuthenticationFilter {

    public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                             FilterChain chain, Authentication authResult)
            throws IOException, ServletException {
        // 认证成功后执行的操作
        System.out.println("User authenticated: " + authResult.getName());
        super.onSuccessfulAuthentication(request, response, chain, authResult);
    }

    @Override
    protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                               AuthenticationException failed)
            throws IOException, ServletException {
        // 认证失败后执行的操作
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed.");
    }
}

然后,在配置类中使用你的自定义过滤器:

@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, CustomBasicAuthenticationFilter customBasicAuthenticationFilter) throws Exception {
        http
            .authorizeRequests(authorize -> authorize
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .addFilterBefore(customBasicAuthenticationFilter, BasicAuthenticationFilter.class); // 添加自定义过滤器
        return http.build();
    }
}
贡献者: Jin