Skip to content

Commit

Permalink
Merge pull request #495 from groldan/gateway_shared_auth_disable_config
Browse files Browse the repository at this point in the history
Allow to disable gateway-shared-auth global filter in the gateway
  • Loading branch information
groldan authored Jul 15, 2024
2 parents 74818f4 + 1ec5e26 commit b25f699
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 49 deletions.
2 changes: 1 addition & 1 deletion config
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* (c) 2020 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.gateway;

import lombok.extern.slf4j.Slf4j;

import org.geoserver.cloud.gateway.filter.GatewaySharedAuhenticationGlobalFilter;
import org.geoserver.cloud.gateway.filter.RouteProfileGatewayFilterFactory;
import org.geoserver.cloud.gateway.filter.StripBasePathGatewayFilterFactory;
import org.geoserver.cloud.gateway.predicate.RegExpQueryRoutePredicateFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

@AutoConfiguration
@Slf4j
public class GatewayApplicationAutoconfiguration {

/**
* Custom gateway predicate factory to support matching by regular expressions on both name and
* value of query parameters
*
* <p>E.g.:
*
* <pre>{@code
* - id: wms_ows
* uri: http://wms-service:8080
* predicates:
* # match service=wms case insensitively
* - RegExpQuery=(?i:service),(?i:wms)
* }</pre>
*/
@Bean
RegExpQueryRoutePredicateFactory regExpQueryRoutePredicateFactory() {
return new RegExpQueryRoutePredicateFactory();
}

/**
* Allows to enable routes only if a given spring profile is enabled
*
* <p>Since the `spring.cloud.gateway.routes` is a list and not a map/dictionary, routes can't
* be added in profiles, because the list is overritten fully. This filter allows to enable
* routes based on profiles from a single list of routes.
*
* <p>E.g.:
*
* <pre>{@code
* - id: catalog
* uri: ...
* predicates:
* - Path=${geoserver.base-path}/api/v1/**
* filters:
* # Expose the catalog and configuration API only if the dev profile is active
* - RouteProfile=dev,403
* }</pre>
*/
@Bean
RouteProfileGatewayFilterFactory routeProfileGatewayFilterFactory(Environment environment) {
return new RouteProfileGatewayFilterFactory(environment);
}

@Bean
StripBasePathGatewayFilterFactory stripBasePathGatewayFilterFactory() {
return new StripBasePathGatewayFilterFactory();
}

@Bean
@ConditionalOnProperty(
name = "geoserver.security.gateway-shared-auth.enabled",
havingValue = "true",
matchIfMissing = true)
GatewaySharedAuhenticationGlobalFilter gatewaySharedAuhenticationGlobalFilter() {
log.info("gateway-shared-auth is enabled");
return new GatewaySharedAuhenticationGlobalFilter();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.gateway;

import lombok.Data;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* For automatic documentation purposes only, as used by the {@literal
* spring-boot-configuration-processor}
*/
@ConfigurationProperties(prefix = "geoserver.security.gateway-shared-auth")
@Data
class SharedAuthConfigurationProperties {

/**
* Enable or disable the Gateway/WebUI Shared Authentication mechanism, where the Gateway works
* as mediator to share the authentication from the GeoServer WebUI with the rest of the
* services.
*/
private boolean enabled = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,19 @@
*/
package org.geoserver.cloud.gateway;

import org.geoserver.cloud.gateway.filter.GatewaySharedAuhenticationGlobalFilter;
import org.geoserver.cloud.gateway.filter.RouteProfileGatewayFilterFactory;
import org.geoserver.cloud.gateway.filter.StripBasePathGatewayFilterFactory;
import org.geoserver.cloud.gateway.predicate.RegExpQueryRoutePredicateFactory;
import org.geoserver.cloud.autoconfigure.gateway.GatewayApplicationAutoconfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

/**
* Spring Cloud Gateway application for GeoServer Cloud
*
* @see GatewayApplicationAutoconfiguration
*/
@SpringBootApplication
@Configuration(proxyBeanMethods = false)
public class GatewayApplication {

public static void main(String[] args) {
new SpringApplicationBuilder(GatewayApplication.class).run(args);
}

@Bean
RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes().build();
}

/**
* Custom gateway predicate factory to support matching by regular expressions on both name and
* value of query parameters
*/
@Bean
RegExpQueryRoutePredicateFactory regExpQueryRoutePredicateFactory() {
return new RegExpQueryRoutePredicateFactory();
}

/** Allows to enable routes only if a given spring profile is enabled */
@Bean
RouteProfileGatewayFilterFactory routeProfileGatewayFilterFactory(Environment environment) {
return new RouteProfileGatewayFilterFactory(environment);
}

@Bean
StripBasePathGatewayFilterFactory stripBasePathGatewayFilterFactory() {
return new StripBasePathGatewayFilterFactory();
}

@Bean
GatewaySharedAuhenticationGlobalFilter gatewaySharedAuhenticationGlobalFilter() {
return new GatewaySharedAuhenticationGlobalFilter();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.geoserver.cloud.autoconfigure.gateway.GatewayApplicationAutoconfiguration
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ spring:
application:
name: gateway-service
jmx.enabled: false
# autoconfigure:
# exclude:
# - org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration
# - org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration
# - org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration
# - org.springframework.cloud.loadbalancer.security.OAuth2LoadBalancerClientAutoConfiguration
# - org.springframework.cloud.loadbalancer.config.LoadBalancerStatsAutoConfiguration

# this service uses the registry (when eureka client is enabled)
eureka.client:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* (c) 2020 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.gateway;

import static org.assertj.core.api.Assertions.assertThat;

import org.geoserver.cloud.gateway.filter.GatewaySharedAuhenticationGlobalFilter;
import org.geoserver.cloud.gateway.filter.RouteProfileGatewayFilterFactory;
import org.geoserver.cloud.gateway.filter.StripBasePathGatewayFilterFactory;
import org.geoserver.cloud.gateway.predicate.RegExpQueryRoutePredicateFactory;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;

class GatewayApplicationAutoconfigurationTest {

private ReactiveWebApplicationContextRunner runner =
new ReactiveWebApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(GatewayApplicationAutoconfiguration.class));

@Test
void testDefaultAppContextContributions() {
runner.run(
context ->
assertThat(context)
.hasNotFailed()
.hasSingleBean(RegExpQueryRoutePredicateFactory.class)
.hasSingleBean(RouteProfileGatewayFilterFactory.class)
.hasSingleBean(StripBasePathGatewayFilterFactory.class)
.hasSingleBean(GatewaySharedAuhenticationGlobalFilter.class));
}

@Test
void disableGatewaySharedAuhenticationGlobalFilter() {
runner.withPropertyValues("geoserver.security.gateway-shared-auth.enabled: false")
.run(
context ->
assertThat(context)
.hasNotFailed()
.doesNotHaveBean(
GatewaySharedAuhenticationGlobalFilter.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>

<root level="info">
<appender-ref ref="STDOUT"/>
</root>

<logger name="org.springframework" level="info"/>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ eureka:
#all Dockerfile files have the default config under that directory
spring.config.activate.on-profile: bootstrap_standalone
spring:
config.location: file:/etc/geoserver/
config.location: ${standalone.config.location:file:/etc/geoserver/}
cloud.config:
enabled: false
---
Expand Down

0 comments on commit b25f699

Please sign in to comment.