我目前正在作为反向代理运行Apache httpd后面的Dropwizard,配置如下:
<VirtualHost *:443>
<Location /api>
ProxyPass "http://my.app.org:8080/api"
<Location>
...
</VirtualHost>使用其他Location设置提供静态资产和一些身份验证。现在,httpd还执行SSL卸载,所以我的Dropwizard只接收普通的HTTP请求。
在我的Dropwizard中,我喜欢返回一个Location头,指示新创建的资源:
@Path("/comment")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
class CommentResource() {
@PUT
fun create(@Context uri: UriInfo, entity: EventComment): Response {
val stored: EventComment = createEntity(entity)
return Response.created(uri.baseUriBuilder.path(MessageStream::class.java)
.resolveTemplate("realmish", entity.realmId)
.path(stored.id.toString()).build()).build()
}这将创建一个具有来自Response的Location头的JerseyUriBuilder。
Location http://my.app.org/api/messages/123在我的SSL应用程序上,它自然无法加载(实际上我很惊讶这不会以http://my.app.org:8080/api/messages/123的形式呈现--也可能是ProxyPassReverse没有提供帮助的原因)。
我知道我可以通过使用baseUriBuilder.scheme("https")强制该方案成为https,但是这会重复发生,并且是一个容易产生错误的来源。
因此,我的问题:我如何才能让泽西生成正确的前端URL,或者成功地使httpd重写由Dropwizard生成的URL?
发布于 2016-01-19 00:46:46
对于泽西,可以使用预匹配的ContainerRequestFilter重写URI。例如
@PreMatching
public class SchemeRewriteFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext request) throws IOException {
URI newUri = request.getUriInfo().getRequestUriBuilder().scheme("https").build();
request.setRequestUri(newUri);
}
}然后把它注册到泽西(Dropwizard)
env.jersey().register(SchemeRewriteFilter.class);编辑
仅当您使用uriInfo.getAbsolutePathBuilder()时,上面的内容才有效。如果您想使用uriInfo.getBaseUriBuilder(),那么您需要使用重载的setRequestUri,它接受基uri作为第一个arg。
URI newUri = request.getUriInfo().getRequestUriBuilder().scheme("https").build();
URI baseUri = request.getUriInfo().getBaseUriBuilder().scheme("https").build();
request.setRequestUri(baseUri, newUri);发布于 2016-08-28 09:19:19
如果使用Jetty,则可以通过向服务器注册org.eclipse.jetty.server.ForwardedRequestCustomizer来避免黑客攻击。这将查看构建基本URI的X-Forwarded-*头。
使用嵌入式Jetty的示例:
Server jettyServer = new Server();
HttpConfiguration config = new HttpConfiguration();
config.addCustomizer(new ForwardedRequestCustomizer());
ServerConnector serverConnector = new ServerConnector(jettyServer,
new HttpConnectionFactory(config));
serverConnector.setPort(8080);
jettyServer.setConnectors(new Connector[] {serverConnector});无论您是否支持反向代理,这似乎都是可行的,所以我不知道为什么它不是默认启用的。
https://stackoverflow.com/questions/34862344
复制相似问题