spring gateway PathRoutePredicateFactory customization

Keywords: network Spring

The requirement is that the company can let the third party develop the application and generate an external domain name for example( xxx.xxx.com )However, access rights of these domain names need to be controlled. The implementation idea is to use spring cloud gateway to place the entry of all application domain names on the gateway through wildcard configuration, and then access the intranet address of the corresponding domain name. The difference between the Internet address and the intranet address is that the main domain has different intranet addresses( xxx.xxxinner.com)

The implementation uses gateway to provide path predicate to intercept all requests, and then forward them to the intranet address After the url is specified for path predicate, it cannot be modified dynamically. A custom interception process is added in the middle.

The gateway PathRoutePredicateFactory is implemented as follows:

RoutePredicateForwardPathFilter set ROUTEgetHandlerInternal method set request path to forward RoutePredicateForwardPathFilter

Check the source code of ForwardPathFilter and find that the execution order of other numbers is 0

Add a custom global filter to replace gateway? Route? Attr to realize the transfer of external network to internal network address

/**
 * Custom block
 */
public class ReplaceAccessUrlFilter implements GlobalFilter, Ordered {

    private static Logger log = LoggerFactory.getLogger(RepalceAccessUrlFilter.class);


    @Value("${application.replace-domain}")
    private String replaceDomain;

    @Value("${application.inner-domain}")
    private String innerDomain;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        URI uri = exchange.getRequest().getURI();
        //Replace the external address with the internal address,
        String routePath = "http://" + (uri.getHost().replace(replaceDomain, innerDomain));
        try {
            log.debug("Conversion access address:{} , {} ", routePath, uri.getPath());
            URI routeUri = new URI(routePath);
            Route oldRoute = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
            Route route = Route.async().predicate((key) -> true).id(oldRoute.getId()).uri(routeUri).build();
            exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, route);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        return chain.filter(exchange);
    }


    @Override
    public int getOrder() {
        return 201;
    }


}

Path configuration

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("replace", r ->
                        r.path("/**").uri("http://xxx.com"))
                .build();
    }

Posted by apsomum on Mon, 11 Nov 2019 08:44:56 -0800