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

凭证在Spring端可用但Angular端登录出现401错误的解决方法

Angular登录触发401错误,但Spring端凭证验证正常的排查方案

问题背景

我在Angular应用中尝试登录时,总是触发401 Unauthorized错误,但使用完全相同的凭证,直接在Spring端(比如Postman调用接口)却能正常完成登录验证。跟着教程开发后尝试了多种方案都没解决,希望能找到问题根源。


相关信息收集

请求头详情

Request URL: http://localhost:8080/ 
Request Method: GET 
Status Code: 401 
Remote Address: [::1]:8080 
Referrer Policy: strict-origin-when-cross-origin 
Access-Control-Allow-Headers: access_token, authorization, content-type 
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE 
Access-Control-Allow-Origin: * 
Access-Control-Max-Age: 4200 
Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
Connection: keep-alive 
Content-Length: 0 
Date: Sat, 18 Sep 2021 16:40:45 GMT 
Expires: 0 
Keep-Alive: timeout=60 
Pragma: no-cache 
Vary: Origin 
Vary: Access-Control-Request-Method 
Vary: Access-Control-Request-Headers 
WWW-Authenticate: Basic realm="Realm" 
WWW-Authenticate: Basic realm="Realm" 
X-Content-Type-Options: nosniff 
X-Frame-Options: DENY 
X-XSS-Protection: 1; mode=block 

Spring Security配置代码

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private CorsConfiguration myCorsFilter;

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 允许无需认证即可访问登录API
        web.ignoring().antMatchers("/login").antMatchers(HttpMethod.OPTIONS, "/**");
        // 允许OPTIONS请求类型
    }

    //CORS配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /* http.cors().and().csrf(). disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .permitAll()
            .anyRequest()
            .fullyAuthenticated()
            .and()
            .httpBasic();*/
        http.addFilterBefore(myCorsFilter, ChannelProcessingFilter.class);
        http.cors();
        http.csrf().disable();
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and()
            .httpBasic();
    }

    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.inMemoryAuthentication()
            .withUser("dave")
            .password("{noop}dave").roles("USER");
    }
}

自定义CorsFilter代码

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsConfiguration implements Filter {
    /**
     * 用于HTTP请求和响应的CORS过滤器
     */
    public void CORSFilter() {
    }

    /**
     * 对每个HTTP请求执行过滤操作
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "4200");
        response.setHeader("Access-Control-Allow-Headers", "access_token, authorization, content-type");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    /**
     * 销毁方法
     */
    @Override
    public void destroy() {
    }

    /**
     * 初始化CORS过滤器
     */
    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }
}

排查与解决步骤

我梳理了几个核心问题点,按优先级排查:

1. 请求路径与方法完全错误

看你的请求头,Angular发送的是GET请求到根路径/,但你的Spring Security明明配置了web.ignoring().antMatchers("/login")——也就是只有/login接口不需要认证,根路径/属于/**的范围,会被要求完全认证,自然返回401。

  • 修复:立即修正Angular端的登录请求,确保请求URL是http://localhost:8080/login,并且使用POST方法(登录请求用GET不安全,Spring Security默认的登录处理也针对POST)。

2. 配置中的转义引号导致路径匹配失效

你的配置代码里所有路径用的是"/login"这种HTML转义的引号,这会导致Spring无法正确识别路径,/login接口根本没被加入到忽略认证的列表里,所以登录请求也会被拦截返回401。

  • 修复:把所有"替换成正常的双引号",比如web.ignoring().antMatchers("/login")。

3. CORS配置冲突

你同时启用了Spring Security自带的http.cors()和自定义的CorsConfiguration Filter,这两种配置会互相干扰,可能导致请求头异常或者拦截顺序错误。

  • 修复:二选一即可,推荐用Spring Security原生的CORS配置更稳妥:
    1. 删除自定义的CorsConfiguration Filter类
    2. 在Spring Security配置里添加CORS配置源:
      @Bean
      CorsConfigurationSource corsConfigurationSource() {
          CorsConfiguration configuration = new CorsConfiguration();
          configuration.setAllowedOrigins(Arrays.asList("*"));
          configuration.setAllowedMethods(Arrays.asList("POST", "PUT", "GET", "OPTIONS", "DELETE"));
          configuration.setAllowedHeaders(Arrays.asList("access_token", "authorization", "content-type"));
          configuration.setMaxAge(4200L);
          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
          source.registerCorsConfiguration("/**", configuration);
          return source;
      }
      
    3. 修改configure(HttpSecurity)方法中的CORS配置:
      http.cors().configurationSource(corsConfigurationSource())
          .and().csrf().disable()
          .authorizeRequests()
              .antMatchers("/login").permitAll() // 直接在这里放行登录接口,比WebSecurity更清晰
              .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
              .anyRequest().fullyAuthenticated()
          .and().httpBasic();
      

4. Basic认证的凭证传递方式

如果你的登录是用Basic认证,Angular端需要把用户名和密码用Base64编码后放在Authorization头里,格式是Authorization: Basic dGFzOmRhc2=(这里dGFzOmRhc2=是tas:das的Base64编码)。不过因为你已经放行/login接口,登录请求不需要带这个头,只需要把用户名密码放在POST请求的体里即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 14:22:35