具有嵌入式服务器和Spring Boot的Cors可以工作,但是在使用tomcat 9进行部署时不起作用

问题描述 投票:0回答:1

我正在开发一个使用angular的Web应用程序,该应用程序由使用spring boot生成的api服务,因此显然我需要在服务器上启用cors。

我使用以下课程:

包含以下内容的RestConfig类:

@Configuration
public class RestConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:4200");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

我的SpringSecurityConfig如下:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    private MediaUserDetailsService mediaUserDetailsService;
    private MediaUserRepository mediaUserRepository;

    public SpringSecurityConfig(MediaUserDetailsService mediaUserDetailsService, MediaUserRepository userRepository) {
        this.mediaUserDetailsService = mediaUserDetailsService;
        this.mediaUserRepository = userRepository;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            //enable cors
            .cors()
            .and()
            // remove csrf and state in session because in jwt we do not need them
            .csrf().disable()
            // add jwt filters (1. authentication, 2. authorization)
            .authorizeRequests()
//          // configure access rules
//          .antMatchers(HttpMethod.OPTIONS, "/media/users").permitAll()
//          .antMatchers(HttpMethod.POST, "/media/users").permitAll()
//          .antMatchers(HttpMethod.OPTIONS, "/login", "/media/users").permitAll()
//          .antMatchers(HttpMethod.POST, "/login", "/media/users").permitAll();
//          .antMatchers("/media/videos").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .addFilter(new JwtAuthenticationFilter(authenticationManager()))
            .addFilter(new JwtAuthorizationFilter(authenticationManager(),  this.mediaUserRepository))
            .exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/media/users");
    }

    @Bean
    DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(this.mediaUserDetailsService);

        return daoAuthenticationProvider;
    }

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

与嵌入式服务器一起运行服务器代码时(即通过使用mvn spring-boot:run),我的应用程序运行良好,可以执行跨源请求,并且没有问题。

但是我想将我的应用程序托管在使用tomcat 9.0.24的主机上。因此,出于测试目的,我在笔记本电脑上安装了tomcat 9.0.24。然后,我构建一个已经部署在其上的战争文件。

并且现在尝试访问端点时使用同一个Web应用程序与angular,我得到Access to XMLHttpRequest at 'http://localhost:8080/media/users' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我不明白为什么它可以与我的嵌入式服务器一起使用,而不是在tomcat上进行部署时。我试图在网络上找到一些解决方案(谷歌是我的朋友)和stackoverflow,但没有运气。

[如果需要,这里是我用angular发送的请求代码:

authenticate(credentials): Observable<any> {
  return this.http.post(this.API + '/login', credentials, {observe: 'response'});
}

感谢您的任何答复,

angular spring-boot tomcat9
1个回答
0
投票

如果没有将angular&spring-boot应用程序包装为war文件,则必须在angular root项目中定义一个代理配置文件,并在package.json中配置此文件。因此,无论何时启动角度服务器,它都会读取该文件并将所有角度请求代理到spring-boot api。

proxy.conf.json

{
    "/api": {
    "target": "http://localhost:8080/<context-path, if you have any>/",
    "secure": false,
    }
}

在package.json中配置此文件

"scripts": {
"start":"ng serve --proxy-config proxy.conf.json",
}

启动您的角度服务器:

ng start

检查您的上下文路径和api请求。如果您的spring-boot api不使用/ api进行统计,请使用"pathRewrite": {"^/api" : ""}覆盖api值为空。

© www.soinside.com 2019 - 2024. All rights reserved.