项目场景:
springcloudgateway 作为网关,支持http和https,服务间使用http
问题解决:
ssl文件生成方式:
keytool -genkeypair -alias client -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
springcloudgateway网关支持https,官网配置(实测可用):
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:keystore.p12
key-store-type: PKCS12
springcloudgateway网关支持http:
package cn.com.test.gateway.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.net.URI;
import java.net.URISyntaxException;
@Configuration
public class HttpToHttpsRedirectConfig {
@Value("${server.http.port}")
private int httpPort;
@Value("${server.port}")
private int serverPort;
@PostConstruct
public void startRedirectServer() {
NettyReactiveWebServerFactory httpNettyReactiveWebServerFactory = new NettyReactiveWebServerFactory(httpPort);
httpNettyReactiveWebServerFactory.getWebServer((request, response) -> {
URI uri = request.getURI();
URI httpsUri;
try {
httpsUri = new URI("https", uri.getUserInfo(), uri.getHost(), serverPort, uri.getPath(), uri.getQuery(), uri.getFragment());
} catch (URISyntaxException e) {
return Mono.error(e);
}
response.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
response.getHeaders().setLocation(httpsUri);
return response.setComplete();
}).start();
}
}
}
配置项:
server:
http:
port: 8080
port: 443
ssl:
enabled: true
key-alias: scg
key-store: classpath:ssl/test.pfx
key-store-password: 6540CNd4Whw
keyStoreType: PKCS12
网关https转发到http:
package com.dp.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.URI;
/**
*/
@Component
public class HttpsToHttpFilter implements GlobalFilter, Ordered {
private static final int HTTPS_TO_HTTP_FILTER_ORDER = 10099;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI originalUri = exchange.getRequest().getURI();
ServerHttpRequest request = exchange.getRequest();
ServerHttpRequest.Builder mutate = request.mutate();
String forwardedUri = request.getURI().toString();
if (forwardedUri != null && forwardedUri.startsWith("https")) {
try {
URI mutatedUri = new URI("http",
originalUri.getUserInfo(),
originalUri.getHost(),
originalUri.getPort(),
originalUri.getPath(),
originalUri.getQuery(),
originalUri.getFragment());
mutate.uri(mutatedUri);
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
ServerHttpRequest build = mutate.build();
return chain.filter(exchange.mutate().request(build).build());
}
/**
* 由于LoadBalancerClientFilter的order是10100,
* 要在LoadBalancerClientFilter执行之前将Https修改为Http,需要设置
* order为10099
* @return
*/
@Override
public int getOrder() {
return HTTPS_TO_HTTP_FILTER_ORDER;
}
}