3

I'm trying to persist user in http session and verify authentication request inside Gateway by using a custom filter. I found a similar question too:

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);
  }
}

By adding a custom filter, and attempting to read/write session attribute, as I observed in debug mode, the function inside map() never gets executed, and nothing gets print out in the terminal. (Unsurprisingly, downstream service cannot read userId from session even though both gateway and service share the same session).

Why is it not working? Here's a minimal reproduced version: Github repo, please take a look.

Enfield Li
  • 1,952
  • 1
  • 8
  • 23
  • I tried [`GlobalFilters`](https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters) but to no avail. It seems like it's impossible to do this inside Gateway. Guess I'll use GWT in the end. And access header takes minimum amount of fuss. – Enfield Li Sep 17 '22 at 04:50

1 Answers1

0

Found a workaround:

By setting up a servlet application as a downstream service that does authorization, and then reading/writing session inside the "authorization service" will be relatively easier (since the gateway and the direct downstream service will be sharing the same session).

As to the whole authentication/authorization part in this microservice architecture, I found out that using JWT is more preferable, and it's recommended that it should be stateless in between services, while gateway can be stateful, so as to share session with the said "authorization service".

A great answer explaining JWT implementation visually.

Enfield Li
  • 1,952
  • 1
  • 8
  • 23