提问者:小点点

如何在Spring Cloud Gateway中读写会话属性?


我正在尝试将用户保留在超文本传输协议会话中,并使用自定义过滤器验证网关内的身份验证请求。我也发现了类似的问题:

@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();
  }
@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,请查看。


共1个答案

匿名用户

通过设置一个servlet应用程序作为下游服务来做授权,然后读/写会话内部的“授权服务”将相对容易(因为网关和直接下游服务将共享同一个会话)。

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

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