我正在开发一个使用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应用程序包装为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值为空。