- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑:请阅读更新,问题已发生重大变化。
我在这方面受到了严重的阻碍。我有一个 spring webflux 应用程序,我正在尝试在其上启用 CORS header ,以便我能够在同一浏览器 session 中执行来自不同来源的请求。但无论我做什么,CORS header 都会被删除(即使我手动将它们放入 ServerResponse 中)。我使用的 security/和 config/中的一些类是:
package com.document.feed.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
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 reactor.core.publisher.Mono;
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private SecurityContextRepository securityContextRepository;
@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
String[] patterns = new String[] {"/auth/**", "/vanillalist"};
return http
.exceptionHandling()
.authenticationEntryPoint((swe, e) -> Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
})).accessDeniedHandler((swe, e) -> Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
})).and()
.csrf().disable()
.authenticationManager(authenticationManager)
.securityContextRepository(securityContextRepository)
.authorizeExchange()
.pathMatchers(patterns).permitAll()
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.anyExchange().authenticated()
.and()
.build();
}
}
SecurityContextRepository.java
package com.document.feed.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import com.document.feed.config.JwtTokenUtil;
import reactor.core.publisher.Mono;
@Component
public class SecurityContextRepository implements ServerSecurityContextRepository {
private static final Logger logger = LoggerFactory.getLogger(SecurityContextRepository.class);
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Override
public Mono save(ServerWebExchange serverWebExchange, SecurityContext sc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Mono load(ServerWebExchange serverWebExchange) {
System.out.println("serverWebExchange:" + serverWebExchange.getAttributes());
ServerHttpRequest request = serverWebExchange.getRequest();
String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
String authToken = null;
if (authHeader != null && authHeader.startsWith(JwtTokenUtil.TOKEN_PREFIX)) {
authToken = authHeader.replace(JwtTokenUtil.TOKEN_PREFIX, "");
}else {
logger.warn("couldn't find bearer string, will ignore the header.");
}
System.out.println("SecurityContextRepository.authToken=" + authToken +
"\nauthHeader=" + authHeader);
String username;
try {
username = jwtTokenUtil.getUsernameFromToken(authToken);
} catch (Exception e) {
username = null;
}
System.out.println("SecurityContextRepository.username:" + username);
if (authToken != null) {
Authentication auth = new UsernamePasswordAuthenticationToken(authToken, authToken);
return authenticationManager.authenticate(auth).map((authentication) -> {
SecurityContextHolder
.getContext().setAuthentication((Authentication) authentication);
return new SecurityContextImpl((Authentication) authentication);
});
} else {
return Mono.empty();
}
}
}
package com.document.feed.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import com.sun.org.apache.xerces.internal.parsers.SecurityConfiguration;
@Configuration
@EnableWebFlux
@Import({CorsConfiguration.class, SecurityConfiguration.class})
public class CorsGlobalConfiguration implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
corsRegistry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(false)
.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");
}
}
看看,Access-Control-Allow-*
header 如何被删除,而 Access-Control-Request-*
却保留在响应 header 中。
chrome 控制台中出现的错误:
fetch('http://localhost:8080/vanillalist', {
method: 'GET',
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
})
.then(res => res.json())
.then(console.log)
Promise {<pending>}
2VM778:1 OPTIONS http://localhost:8080/vanillalist 404 (Not Found)
(anonymous) @ VM778:1
:3000/#/:1 Access to fetch at 'http://localhost:8080/vanillalist' from origin 'http://localhost:3000' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
:3000/#/:1 Uncaught (in promise) TypeError: Failed to fetch
更新2: @mikeb 请求的 curl -v
,在请求 header 中添加 OPTIONS
后。
(venv) NB292:scaligent devansh.dalal$ curl -v http://localhost:8080/vanillalist > /tmp/r.txt
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /vanillalist HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< transfer-encoding: chunked
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Content-Type: application/json
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< X-XSS-Protection: 1 ; mode=block
< Referrer-Policy: no-referrer
<
{ [8 bytes data]
100 1350k 0 1350k 0 0 19.9M 0 --:--:-- --:--:-- --:--:-- 19.9M
* Connection #0 to host localhost left intact
更新3:问题现在已经减少,可以处理OPTIONS
类型的请求。
最佳答案
使用 Spring Security 后重写 addCorsMappings() 无效。只需定义一个 CorsConfigurationSource
bean 即可为您工作。看下面的代码,它是用kotlin编写的,
@Configuration
class GlobalWebConfig {
private fun corsConfiguration(corsProperties: CorsProperties): CorsConfiguration {
val corsConfiguration = CorsConfiguration()
corsConfiguration.allowCredentials = corsProperties.credentials
corsConfiguration.allowedHeaders = corsProperties.headers
corsConfiguration.allowedOrigins = corsProperties.origins
corsConfiguration.allowedMethods = corsProperties.methods
corsConfiguration.maxAge = corsProperties.age
return corsConfiguration
}
@Bean
fun corsConfigurationSource(corsProperties: CorsProperties): CorsConfigurationSource {
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", corsConfiguration(corsProperties))
return source
}
}
关于java - spring webflux CORS header 被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59734599/
我希望缓存Mono(仅在成功的情况下),这是WebClient调用的结果。 通过阅读项目 react 堆插件文档,我觉得CacheMono不太适合,因为它也存储了我不想要的错误。 因此,我没有使用Ca
我用 webflux 与 网易和 jdbc ,所以我以下一种方式包装阻塞 jdbc 操作: static Mono fromOne(Callable blockingOperation) {
有人可以告诉我或使用 提供现成的 CRUD 示例吗? WebFlux、RScoket 和 Spring(或 SpringBoot) ? 我研究了 RSocket 文档, WebFlux ,也写了我的简
我正在通过代理连接使用ssl服务测试webclient,但是使用安全ssl连接时出现以下错误。 你知道是什么问题吗? 堆栈跟踪: {"timestamp":"2019-10-29T18:35:43.5
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { Flux body = exchange.
我创建了一个过滤器,我可以在其中访问有效负载的主体并对其执行一些逻辑(现在假设我记录主体)。在最后一步中,我返回了 Mono,但是当请求通过 Controller 继续发送到服务时,它会抛出请求正文丢
上次我在考虑在我们的应用程序中正确使用记录器。例如,我有一个返回用户流的 Controller ,但在日志中,我看到“获取用户”日志正在被另一个线程而不是处理管道上的线程记录,但这是一个好方法吗? @
我正在使用带有 Netty 的 Spring Webflux (2.0.3.RELEASE) 并尝试了解服务器和 Web 客户端如何使用线程。我用 WebClient 编写了一些带有 http 调用链
我面临一个问题。我正在使用 Spring Webflux 并行调用一些 API。如果任何子线程面临任何问题,它需要记录请求。现在的问题是,用于记录一个普通的 POJO 类,其中有一个静态方法通过 Ap
我试图用 JSP 配置 Spring WebFlux。我在 Spring WebFlux 中没有看到任何支持 JSTL View 的 View 类。这是否意味着我们不能使用 Spring WebFlu
我正在寻找一种在响应式(Reactive) API 中使用计划任务的方法。 我知道它使用线程池,所以它与 webflux 组件不太兼容。 你有同等的人来做这项工作吗? 非常感谢 萨维留 最佳答案 有几
我曾经调用 HttpServletRequest.getRemoteAddr() 来获取客户端 ip。 我想知道如何通过 ServerWebExchange 获得它。 我最好的猜测是: serve
我想使用 spring webflux 以 react 方式流式传输文件。 我的端点应该看起来更具体什么是对象的类型? @GetMapping("/file") Flux file() { /
我无法让我的响应式(Reactive)代码以一种常见的方式处理错误。理想的方式是使用可重用的组件,我可以将其作为依赖项添加到其他项目中。 过去,我们使用 @RestControllerAdvise 通
我们正在尝试对 Webflux 使用react。我们将 Jaegar 与 Istio 用于检测目的。 Jaegar 非常了解 Spring MVC 端点,但似乎对 WebFlux 根本不起作用。 我正
我是响应式(Reactive)编程和 Spring WebFlux 的新手。我想让我的 App 1 通过 Flux 发布 Server Sent 事件,我的 App 2 持续监听它。 我希望 Flux
我正在我的项目中尝试新的 ReactiveQuerydslPredicateExecutor 但我找不到 findAll(Predicate, Pageable) 的方法,就像我在 QueryDslP
我正在使用 Spring WebFlux webclient 进行 REST 调用。我已经在 3000 上配置了连接超时毫秒,相应地: WebClient webClient = WebClient.
我想测量使用 WebFlux 进行的一些异步调用的长度。我一直在阅读各种来源,据我所知,@Timed 注释与 AspectJ 一起工作,基本上只是在方法调用之前启动一个计时器,然后停止它。这显然不适用
我有一个 Reactor Kafka 应用程序,它无限期地使用来自主题的消息。我需要公开一个健康检查 REST 端点,它可以指示此过程的健康状况——主要是想知道 Kafka 接收器通量序列是否已终止,
我是一名优秀的程序员,十分优秀!