Spring Boot中如何实现支持Basic Auth的API end point身份校验
Spring Boot 实现Basic Auth认证接口方案
Spring Security是实现该需求最稳妥的原生组件,已经完整实现了HTTP Basic认证的标准规范,不需要手动解析请求头、手写校验逻辑,能避免自实现带来的各类安全漏洞。
1. 引入依赖
如果是Maven项目,在pom.xml中引入Spring Security starter:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
如果是Gradle项目,引入对应依赖即可:
implementation 'org.springframework.boot:spring-boot-starter-security'
2. 编写认证配置
新建安全配置类,配置认证规则、用户校验逻辑、密码加密方式,以下代码兼容Spring Boot 2.7+、3.x版本:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import javax.servlet.http.HttpServletResponse; @Configuration @EnableWebSecurity public class BasicAuthConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 配置接口访问规则 .authorizeHttpRequests(auth -> auth // 可在此配置放行不需要认证的路径,比如公开接口 // .requestMatchers("/api/public/**").permitAll() // 其余所有接口都需要认证 .anyRequest().authenticated() ) // 开启标准HTTP Basic认证支持 .httpBasic(Customizer.withDefaults()) // API场景关闭CSRF防护,避免POST/PUT等非GET请求被拦截 .csrf(csrf -> csrf.disable()) // 可选:自定义认证失败返回格式 .exceptionHandling(ex -> ex .authenticationEntryPoint((request, response, authException) -> { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":401,\"msg\":\"用户名或密码校验失败\"}"); }) ); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { // 密码加密器,存储、校验密码统一用该实例,禁止明文存储密码 return new BCryptPasswordEncoder(); } // 固定账号场景:内存用户配置,适合测试、固定调用方的场景 @Bean public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { UserDetails apiCaller = User.withUsername("yourApiUsername") .password(passwordEncoder.encode("yourApiPassword")) .roles("API_ACCESS") .build(); return new InMemoryUserDetailsManager(apiCaller); } // 动态账号场景:对接数据库校验用户(注释掉上面的内存UserDetailsService,启用该Bean即可) /* @Bean public UserDetailsService userDetailsService() { return username -> { // 替换为自己的业务逻辑:根据用户名从数据库查询账号信息 ApiUser dbUser = apiUserMapper.selectByUsername(username); if (dbUser == null) { // 抛出该异常后Spring Security会自动判定为认证失败 throw new UsernameNotFoundException("账号不存在"); } return User.withUsername(dbUser.getUsername()) .password(dbUser.getBcryptEncryptedPassword()) .roles(dbUser.getRoleList()) .build(); }; } */ }
3. 接口调用规则
配置完成后,所有接口会自动开启Basic认证校验,客户端请求需要符合以下规则:
- 请求头携带
Authorization字段,值格式为Basic <base64(用户名:密码)> - 示例:用户名是
yourApiUsername、密码是yourApiPassword,先拼接成字符串yourApiUsername:yourApiPassword,对该字符串做Base64编码后,最终请求头为Authorization: Basic eW91ckFwaVVzZXJuYW1lOnlvdXJBcGlQYXNzd29yZA== - 认证通过后接口正常返回业务数据,认证失败返回配置的401错误信息
注意事项
- 生产环境必须用BCrypt等强哈希算法加密存储密码,绝对不能明文存储、明文比对密码
- 如果只需要给特定路径的接口加认证,在
authorizeHttpRequests配置里通过路径匹配规则细化即可 - 不要自己写拦截器/过滤器手动解析Authorization头实现校验,Spring Security的实现已经覆盖了RFC标准里的所有边界场景,自实现很容易出现编码解析错误、时序攻击等安全漏洞
内容的提问来源于stack exchange,提问作者Pradip
相关产品推荐
相关产品推荐

