You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot接口调用遇401 Unauthorized错误,求排查原因

问题分析:SpringBoot HttpBasic认证返回401 Unauthorized错误

问题场景

在SpringBoot项目中配置了HttpBasic认证,内存用户名为user、密码password,但调用GET http://localhost:6000/时返回401 Unauthorized。相关代码如下:

ResourceController代码

package controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ResourceController {

    @GetMapping("/")
    public String getResource() {
        return "a value...";
    }

}

SpringSecurityConfig代码

package configuration;

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.http.SessionCreationPolicy;
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.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SpringSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .csrf(csrf -> csrf.disable())
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .httpBasic(Customizer.withDefaults())
                .build();
    }

    @Bean
    public UserDetailsService users() {
        UserDetails user = User.builder().username("user").password(passwordEncoder().encode("password")).roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }


    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

项目依赖包含spring-boot-starter-web、spring-boot-starter-oauth2-resource-server,端口配置为6000。

可能的原因及解决方法

1. OAuth2资源服务器依赖与HttpBasic认证冲突

spring-boot-starter-oauth2-resource-server依赖会自动引入OAuth2资源服务器的自动配置,该配置优先级高于自定义的HttpBasic配置,导致Spring Security默认期望请求携带Bearer Token而非HttpBasic认证信息。

解决方法:

  • 如果不需要OAuth2资源服务器功能,直接从pom.xml中移除spring-boot-starter-oauth2-resource-server依赖;
  • 如果必须保留该依赖,需要在Security配置中明确禁用OAuth2资源服务器的自动配置,修改filterChain方法:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .httpBasic(Customizer.withDefaults())
            // 禁用OAuth2资源服务器自动配置
            .oauth2ResourceServer(oauth2 -> oauth2.disable())
            .build();
}

2. Postman中HttpBasic认证配置错误

确保在Postman中正确设置认证信息:

  • 打开请求的Authorization选项卡;
  • 类型选择Basic Auth;
  • 输入用户名user和密码password,Postman会自动生成符合规范的Authorization请求头,避免手动构造时出现编码错误。

3. 密码编码的潜在验证问题

虽然当前代码中密码编码逻辑正确,但可以手动验证编码后的密码是否匹配:

// 验证密码是否匹配
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
System.out.println(encoder.matches("password", encoder.encode("password")));

如果输出true则编码逻辑无问题,否则需检查编码逻辑是否存在作用域或实例化异常。

内容的提问来源于stack exchange,提问作者Glaxer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 19:47:30