Skip to content
Advertisement

implementation of Gateway Global filter in Kotlin to Java implementation

I have a scenario that I have some microservices, cloud gateway and eureka server. All microservices and cloud gateway registered on the eureka server. Cloud gateway will securing all the downstream services. When any user want to access the service first it will fill out the username and password for authentication on the cloud gateway. If the user will be authentic then it will access the service by the gateway route that is already set in application.properties file but I want when the user will authentic and access the service then I can also get user authentic credential in downstream services or microservices that are behind the cloud gateway. In other word I want to getting principle values that is set on the gateway in downstream service. So, After searching many days I got a Global Filter Implementation link but this filter code in Kotlin and I am not familiar with Kotlin, So unable to understand of this. I want to implement this in Java. Basically this filter for adding username and user roles to headers of downstream services request. How can I convert this filter into java.

Here is the Workflow

Here is the cloud gateway configuration

@Configuration
@EnableWebFluxSecurity
public class GatewaySecurityConfig{

     @Bean
        public MapReactiveUserDetailsService userDetailsService() {
            UserDetails user = User.builder()
                    .username("user")
                    .password(passwordEncoder().encode("password"))
                    .roles("USER")
                    .build();
            UserDetails admin = User.builder()
                    .username("admin")
                    .password(passwordEncoder().encode("password"))
                    .roles("USER","ADMIN")
                    .build();
            return new MapReactiveUserDetailsService(user, admin);
        }
     
        @Bean
        public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
            http
                .authorizeExchange()
                .anyExchange().authenticated()
                .and()
                .httpBasic(withDefaults())
                .formLogin();
            return http.build();
        }
        
        
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder(8);
        }
        
} 

Global Filter Implementation in Kotlin and I want code of this in Java8

@Component
class AddCredentialsGlobalFilter : GlobalFilter {

    private val usernameHeader = "logged-in-user"
    private val rolesHeader = "logged-in-user-roles"

    override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain) = exchange.getPrincipal<Principal>()
            .flatMap { p ->
                val request = exchange.request.mutate()
                        .header(usernameHeader, p.name)
                        .header(rolesHeader, (p as Authentication).authorities?.joinToString(";") ?: "")
                        .build()
                chain.filter(exchange.mutate().request(request).build())
            }
}

Application.properties Configuration

server:
  port: 8080
 
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8083/eureka 

spring:
  main:
    allow-bean-definition-overriding: true
  application:
    name: gateway
  cloud:
    gateway:
      routes:
      - id: userModule
        uri: lb://user
        predicates:
        - Path=/user/**

Advertisement

Answer

I believe it’s something like following

@Component
public class AddCredentialsGlobalFilter implements GlobalFilter {

    private final String usernameHeader = "logged-in-user";
    private final String rolesHeader = "logged-in-user-roles";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return exchange.getPrincipal().flatMap(p -> {
            List<GrantedAuthority> authorities = (List<GrantedAuthority>) ((Authentication)p).getAuthorities();
            String rolesString = authorities != null 
                    ? authorities.stream().map(Object::toString).collect(Collectors.joining(";"))
                    : "";
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .header(usernameHeader, p.getName())
                    .header(rolesHeader, rolesString)
                    .build();
            return chain.filter(exchange.mutate().request(request).build());
        });
    }
}

Advertisement