使用带有 JWT 的 Angular 和 Spring Boot 服务的 PUT 请求出现 403 错误

Posted

技术标签:

【中文标题】使用带有 JWT 的 Angular 和 Spring Boot 服务的 PUT 请求出现 403 错误【英文标题】:403 error with PUT request using angular and spring boot service with JWT 【发布时间】:2021-04-18 00:57:50 【问题描述】:
package com.example.invoiceapp.security;

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;


@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    private UserDetailsService userDetailsService;
    private static final String[] AUTH_WHITELIST =  "/v2/api-docs", "/swagger-resources", "/swagger-resources/**",
            "/configuration/ui", "/configuration/security", "/swagger-ui.html", "/webjars/**" ;

    public SecurityConfiguration(UserDetailsService userDetailsService) 
        this.userDetailsService = userDetailsService;
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.cors().configurationSource(configurationSource()).and().csrf().disable().authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll()
                .antMatchers(HttpMethod.POST, "/authenticate/signup").permitAll().anyRequest().authenticated().and()
                .exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)).and()
                .addFilter(new AuthenticationFilter(authenticationManager()))
                .addFilter(new AuthorizationFilter(authenticationManager())).sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().formLogin().usernameParameter("email");
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder() );
    

    @Bean
    CorsConfigurationSource configurationSource() 
        
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"));
        configuration.setAllowCredentials(true);
//      configuration.addAllowedOrigin("*");
//      configuration.addAllowedHeader("*");
//      configuration.addAllowedMethod("*");
        
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
        return source;
    
    
    @Bean
    public BCryptPasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    


我正在尝试从前端 Angular 应用程序发出 PUT 请求,但 OPTIONS 的飞行前请求失败并给出错误:

CORS 策略已阻止从源“http://localhost:4200”访问“https://invoice-backend-heroku.herokuapp.com/api/invoices/5fe8353905dfdc66e95e7269”处的 XMLHttpRequest:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

即使我允许所有来源和方法。我不确定如何配置我的 corsconfiguration 以使其工作。我对同一个 Spring Boot 服务的 POST 请求和 GET 请求一样工作正常。

【问题讨论】:

【参考方案1】:
      @Bean
      CorsConfigurationSource configurationSource() 
        
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"));
        configuration.setAllowCredentials(true);
        
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration.applyPermitDefaultValues());
        return source;
    

您应该使用 source.registerCorsConfiguration("/**", configuration.applyPermitDefaultValues()); 中的引用对象配置而不是创建新对象 new CorsConfiguration()

【讨论】:

感谢您注意到,我更改了它,直到我在配置中明确添加我的域 configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200")); 参考:***.com/questions/19743396/…

以上是关于使用带有 JWT 的 Angular 和 Spring Boot 服务的 PUT 请求出现 403 错误的主要内容,如果未能解决你的问题,请参考以下文章

express-jwt 和带有 cookie 的 Angular 9:未在“授权”标头中设置令牌

带有 PHP 和 Angular.js 的 JWT(JSON Web 令牌)

带有用户角色参数的 Angular2 路由 canActivate 和 AuthGuard (JWT)

带有 Angular 8 和 Springboot 2 的 JWT:JWT 字符串必须恰好包含 2 个句点字符

带有jwt的Angular 2 AuthHttp未连接

带有 jwt cookie 的 Angular 应用程序中的身份验证点