Spring boot zuul 请求重定向错误
Spring boot zuul wrong redirection of request
我正在开发一个 API 网关来将请求重定向到某个微服务。
这是 application.properties 文件的一部分:
# _____ _____.__
# / _ \ ______ ______ ____ ____ _____/ ____\__| ____
# / /_\ \____ \____ \ _/ ___\/ _ \ / \ __\| |/ ___\
# / | \ |_> > |_> > \ \__( <_> ) | \ | | / /_/ >
# \____|__ / __/| __/ \___ >____/|___| /__| |__\___ /
# \/|__| |__| \/ \/ /_____/
server.port=8088
server.servlet.context-path=/PetApp
# __________ .__ _________ _____.__
# \____ /__ __ __ __| | \_ ___ \ ____ _____/ ____\__| ____
# / /| | \ | \ | / \ \/ / _ \ / \ __\| |/ ___\
# / /_| | / | / |__ \ \___( <_> ) | \ | | / /_/ >
# /_______ \____/|____/|____/ \______ /\____/|___| /__| |__\___ /
# \/ \/ \/ /_____/
#Routes for Auth
zuul.routes.tokenGenerator.path=/auth/login
zuul.routes.tokenGenerator.url=http://localhost:8086/PetApp_Auth/auth/generateToken
zuul.routes.tokenGenerator.stripPrefix=false
我正在尝试重定向来自 API 网关 (http://localhost:8080/PetApp/auth/login) to the service running in (http://localhost:8086/PetApp_Auth/auth/generateToken) 的请求
我已经通过邮递员将请求直接发送到微服务,它运行良好。
重要提示:我没有添加任何授权 header 因为这个端点没有安全化(而且它工作得很好)但是我的 auth 微服务中 API 的其余部分是安全化的
但是当我尝试通过 API 网关发送请求时,我得到以下信息:
可以看出,请求被重定向到正确的微服务(Auth 服务),但没有重定向到正确的 URL,因为我对其余端点和 URL 正在显示。
我也试过将之前生成的授权令牌放入header中发送,但我得到的同样是未授权
我做错了什么?
也许您需要在 zuul 或 auth 微服务中禁用 Spring 安全性。只需删除 spring 安全依赖项,确保令牌从 zuul 传递到 auth...
我已经通过添加过滤器解决了。
Zuul 构建了完整的 URL 类服务 service defined URL + PATH,所以我实现了一个删除路径的过滤器,现在请求在其他微服务中得到了完美的接收。
无论如何,我打算更改端点定义,使其具有与微服务中定义的端点路径相同的端点路径,因为对于可变路径,我认为解决这个问题是不可能的。
我还将检查使用其他解决方案,如 nginx 或 varnish,正如@Maxim Sagaydachny 建议的那样
@Component
public class PathConfigFilter extends ZuulFilter {
@Autowired
private ZuulProperties zuulProperties;
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
}
@Override
public boolean shouldFilter() {
return RequestContext.getCurrentContext().getFilterExecutionSummary().toString()
.contains( "PreDecorationFilter[SUCCESS]" );
}
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
String originalRequestPath = (String) context.get(FilterConstants.REQUEST_URI_KEY);
//PathVariable change
URL routeHost = (URL) context.get( "routeHost");
String modifiedPathVariable = processPathVariableRoutes( routeHost.getPath(), originalRequestPath );
if(modifiedPathVariable != null){
try {
URL newUrl = new URL(routeHost,modifiedPathVariable);
context.put("routeHost", newUrl);
} catch (MalformedURLException e) {
throw new ApiGatewayException( ApiGatewayErrorCodes.PATH_VARIABLE_ERROR );
}
}
//Delete the path because the full path is defined in properties
context.put(FilterConstants.REQUEST_URI_KEY, "");
return null;
}
private String processPathVariableRoutes(String routeHost, String requestPath){
if(!routeHost.contains( "*" )){
return null;
}
ArrayList<String> splitedRoute = new ArrayList<>(Arrays.asList(routeHost.split( "/" )));
splitedRoute.remove( 0 );
String context = "/" + splitedRoute.get( 0 );
String realPath = context + requestPath;
return realPath;
}
}
非常感谢。
我正在开发一个 API 网关来将请求重定向到某个微服务。 这是 application.properties 文件的一部分:
# _____ _____.__
# / _ \ ______ ______ ____ ____ _____/ ____\__| ____
# / /_\ \____ \____ \ _/ ___\/ _ \ / \ __\| |/ ___\
# / | \ |_> > |_> > \ \__( <_> ) | \ | | / /_/ >
# \____|__ / __/| __/ \___ >____/|___| /__| |__\___ /
# \/|__| |__| \/ \/ /_____/
server.port=8088
server.servlet.context-path=/PetApp
# __________ .__ _________ _____.__
# \____ /__ __ __ __| | \_ ___ \ ____ _____/ ____\__| ____
# / /| | \ | \ | / \ \/ / _ \ / \ __\| |/ ___\
# / /_| | / | / |__ \ \___( <_> ) | \ | | / /_/ >
# /_______ \____/|____/|____/ \______ /\____/|___| /__| |__\___ /
# \/ \/ \/ /_____/
#Routes for Auth
zuul.routes.tokenGenerator.path=/auth/login
zuul.routes.tokenGenerator.url=http://localhost:8086/PetApp_Auth/auth/generateToken
zuul.routes.tokenGenerator.stripPrefix=false
我正在尝试重定向来自 API 网关 (http://localhost:8080/PetApp/auth/login) to the service running in (http://localhost:8086/PetApp_Auth/auth/generateToken) 的请求 我已经通过邮递员将请求直接发送到微服务,它运行良好。
重要提示:我没有添加任何授权 header 因为这个端点没有安全化(而且它工作得很好)但是我的 auth 微服务中 API 的其余部分是安全化的
但是当我尝试通过 API 网关发送请求时,我得到以下信息:
可以看出,请求被重定向到正确的微服务(Auth 服务),但没有重定向到正确的 URL,因为我对其余端点和 URL 正在显示。
我也试过将之前生成的授权令牌放入header中发送,但我得到的同样是未授权
我做错了什么?
也许您需要在 zuul 或 auth 微服务中禁用 Spring 安全性。只需删除 spring 安全依赖项,确保令牌从 zuul 传递到 auth...
我已经通过添加过滤器解决了。 Zuul 构建了完整的 URL 类服务 service defined URL + PATH,所以我实现了一个删除路径的过滤器,现在请求在其他微服务中得到了完美的接收。 无论如何,我打算更改端点定义,使其具有与微服务中定义的端点路径相同的端点路径,因为对于可变路径,我认为解决这个问题是不可能的。 我还将检查使用其他解决方案,如 nginx 或 varnish,正如@Maxim Sagaydachny 建议的那样
@Component
public class PathConfigFilter extends ZuulFilter {
@Autowired
private ZuulProperties zuulProperties;
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
}
@Override
public boolean shouldFilter() {
return RequestContext.getCurrentContext().getFilterExecutionSummary().toString()
.contains( "PreDecorationFilter[SUCCESS]" );
}
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
String originalRequestPath = (String) context.get(FilterConstants.REQUEST_URI_KEY);
//PathVariable change
URL routeHost = (URL) context.get( "routeHost");
String modifiedPathVariable = processPathVariableRoutes( routeHost.getPath(), originalRequestPath );
if(modifiedPathVariable != null){
try {
URL newUrl = new URL(routeHost,modifiedPathVariable);
context.put("routeHost", newUrl);
} catch (MalformedURLException e) {
throw new ApiGatewayException( ApiGatewayErrorCodes.PATH_VARIABLE_ERROR );
}
}
//Delete the path because the full path is defined in properties
context.put(FilterConstants.REQUEST_URI_KEY, "");
return null;
}
private String processPathVariableRoutes(String routeHost, String requestPath){
if(!routeHost.contains( "*" )){
return null;
}
ArrayList<String> splitedRoute = new ArrayList<>(Arrays.asList(routeHost.split( "/" )));
splitedRoute.remove( 0 );
String context = "/" + splitedRoute.get( 0 );
String realPath = context + requestPath;
return realPath;
}
}
非常感谢。