如何在Spring Cloud Gateway中读取/写入会话属性



我正在尝试将用户持久化到http会话中,并使用自定义过滤器在Gateway中验证身份验证请求。我也发现了一个类似的问题:

SecurityConfig:

@Configuration
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(
ServerHttpSecurity http,
MyAuthenticationFilter myAuthenticationFilter
) {
http
.csrf()
.disable()
.authorizeExchange()
.pathMatchers("/**")
.permitAll()
.and()
.addFilterAt(myAuthenticationFilter, SecurityWebFiltersOrder.FIRST); // custom filter
return http.build();
}

MyAuthenticationFilter:

@Component
public class MyAuthenticationFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
exchange.getSession().map(
session -> {
session.getAttributes().put("userId", "id123");
// It does not print anything
System.out.println("userId in session: " + session.getAttribute("userId"));
return session;
}
);
return chain.filter(exchange);
}
}

通过添加一个自定义过滤器,并尝试读取/写入会话属性,正如我在调试模式中观察到的那样,map()内部的函数永远不会执行,并且不会在终端中打印出任何内容。(毫不奇怪,即使网关和服务共享同一会话,下游服务也无法从会话中读取userId(。

为什么它不起作用?这里有一个最小的复制版本:Github repo,请看一看。

找到了一个解决方法:

通过将servlet应用程序设置为进行授权的下游服务;授权服务";将相对容易(因为网关和直接下游服务将共享同一会话(。

对于这个微服务架构中的整个身份验证/授权部分,我发现使用JWT更可取,建议它在服务之间应该是无状态的,而网关可以是有状态的,以便与上述"共享会话;授权服务";。

直观地解释JWT的实现是一个很好的答案。

最新更新