spring-security 如何在Spring Cloud Gateway中读写session属性?

aor9mmx1  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(490)

我正在尝试在http会话中持久化用户,并使用自定义过滤器验证网关内部的身份验证请求。我也发现了一个similar question

安全配置:

@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,请看一下。

x3naxklr

x3naxklr1#

找到解决方法:

通过将servlet应用程序设置为执行授权的下游服务,“授权服务”内部的阅读/写会话将相对容易一些(因为网关和直接下游服务将共享同一会话)。
对于这个微服务架构中的整个认证/授权部分,我发现使用JWT更可取,并且建议在服务之间应该是无状态的,而网关可以是有状态的,以便与所说的“授权服务”共享会话。
一个great answer,以可视化方式解释JWT实现。

相关问题