带有 Spring 安全 webflux 的 Angular 6 被 CORS 阻止
Posted
技术标签:
【中文标题】带有 Spring 安全 webflux 的 Angular 6 被 CORS 阻止【英文标题】:Angular 6 with Spring security webflux blocked by CORS 【发布时间】:2019-01-27 01:35:05 【问题描述】:我正在尝试编写一个使用 Springs WebFlux Security 的应用程序。在前端 Angular 应用程序中,我将用户带到登录页面,一旦他们登录,应用程序应该重定向到不同的 uri。截至目前,我收到此错误:
Failed to load http://localhost:8080/login: Redirect from
'http://localhost:8080/login' to 'http://localhost:8080/pets' has been
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'http://localhost:4200' is
therefore not allowed access.
目前我不确定为什么会出现 CORS 错误,但这是我对 spring webflux 安全性的了解
@EnableWebFluxSecurity
public class SecurityConfig
@Autowired
private ReactiveUserDetailsService reactiveUserDetailsService;
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http)
http
.authorizeExchange()
.pathMatchers(HttpMethod.POST, "/login").permitAll()
.pathMatchers(HttpMethod.POST, "/logout").permitAll()
.pathMatchers(HttpMethod.POST, "/register").permitAll()
.anyExchange().authenticated()
.and()
.httpBasic().disable()
.csrf().disable()
.formLogin()
.authenticationManager(authenticationManager())
.requiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/login"))
.authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/pets"))
.authenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(new HttpBasicServerAuthenticationEntryPoint()))
.authenticationEntryPoint(new HttpBasicServerAuthenticationEntryPoint())
.and()
.logout()
.logoutSuccessHandler(((exchange, authentication) -> Mono.fromRunnable(() -> exchange.getExchange().getResponse().setStatusCode(HttpStatus.OK))));
return http.build();
@Bean
public ReactiveAuthenticationManager authenticationManager()
UserDetailsRepositoryReactiveAuthenticationManager authManager =
new UserDetailsRepositoryReactiveAuthenticationManager(reactiveUserDetailsService);
authManager.setPasswordEncoder(passwordEncoder());
return authManager;
@Bean
PasswordEncoder passwordEncoder()
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
我有什么遗漏或需要修改的吗?
【问题讨论】:
你确定你可以从4200端口向8080端口发起http请求吗? 【参考方案1】:我遇到了这个问题,我正在使用这个组合:Spring Boot + Webflux + Security。
控制器 @CrossOrigin 不起作用 全球跨域,就像之前的答案中设置的那样,也不起作用这里记录了唯一对我有用的解决方案:
Enable CORS in Spring 5 Webflux?
创建一个 SecurityConfiguration 类
使用这种组合使 CORS 工作的关键是 configuration.applyPermitDefaultValues();
如果您删除该行,它将不起作用
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http)
System.out.println("Security Config");
http
.csrf().disable()
.cors().configurationSource( corsConfigurationSource() ).and()
.authorizeExchange()
.pathMatchers(HttpMethod.POST, "/auth", "/api").permitAll()
.pathMatchers(HttpMethod.GET,"/**").permitAll()
.anyExchange().authenticated();
return http.build();
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
configuration.setMaxAge(3600L);
configuration.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
【讨论】:
我测试了其他解决方案,您链接的解决方案运行良好。但是,当您的 pom.xml 中存在 Spring Security 时,除了您的之外,其他解决方案将不起作用。感谢您分享这个解决方案。【参考方案2】:您应该在 Spring 应用程序的配置中定义 CORS 映射。
这是我的示例:
@Configuration
@EnableWebFlux
@Import(CoreConfiguration.class, SecurityConfiguration.class)
public class ServicesConfiguration implements WebFluxConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/api/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.exposedHeaders("Access-Control-Allow-Origin",
"Access-Control-Allow-Methods",
"Access-Control-Allow-Headers",
"Access-Control-Max-Age",
"Access-Control-Request-Headers",
"Access-Control-Request-Method")
.maxAge(3600);
// Add more mappings...
事实是,如果我测试来自 Postman 的请求,没有 CORS 问题,它会出现在前端(实际上是浏览器)需要适当的 CORS 标头时。
参考资料:
https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html
https://github.com/spring-projects/spring-framework/blob/master/src/docs/asciidoc/web/webflux-cors.adoc
【讨论】:
【参考方案3】:你做得完全正确,但你需要将你的端口 8080 配置为代理端口。
只需在项目的根目录中创建一个名为 proxy.conf.json 的新文件,并在其中定义您的代理,如下所示。
"/login":
"target":
"host": "localhost",
"protocol": "http:",
"port": 8080
,
"secure": false,
"changeOrigin": true,
"logLevel": "info"
同样你也可以绑定另一个 url。
现在在您运行 Angular 应用程序时进行下一步。执行以下命令。
ng 服务 --proxy-config proxy.conf.json
【讨论】:
以上是关于带有 Spring 安全 webflux 的 Angular 6 被 CORS 阻止的主要内容,如果未能解决你的问题,请参考以下文章
WebTestClient - 带有 Spring Boot 和 Webflux 的 CORS
带有 MultipartFile 的 Spring Webflux 415
带有 Spring WebFlux 的 RestController:必需参数不存在
Spring Security WebFlux - 带有身份验证的主体