首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何强制UriBuilder使用https?

如何强制UriBuilder使用https?
EN

Stack Overflow用户
提问于 2016-01-18 19:15:50
回答 2查看 3.4K关注 0票数 3

我目前正在作为反向代理运行Apache httpd后面的Dropwizard,配置如下:

代码语言:javascript
复制
<VirtualHost *:443>
  <Location /api>
    ProxyPass "http://my.app.org:8080/api"
  <Location>
  ...
</VirtualHost>

使用其他Location设置提供静态资产和一些身份验证。现在,httpd还执行SSL卸载,所以我的Dropwizard只接收普通的HTTP请求。

在我的Dropwizard中,我喜欢返回一个Location头,指示新创建的资源:

代码语言:javascript
复制
@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()
}

这将创建一个具有来自ResponseLocation头的JerseyUriBuilder

代码语言:javascript
复制
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?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-19 00:46:46

对于泽西,可以使用预匹配的ContainerRequestFilter重写URI。例如

代码语言:javascript
复制
@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)

代码语言:javascript
复制
env.jersey().register(SchemeRewriteFilter.class);

编辑

仅当您使用uriInfo.getAbsolutePathBuilder()时,上面的内容才有效。如果您想使用uriInfo.getBaseUriBuilder(),那么您需要使用重载的setRequestUri,它接受基uri作为第一个arg。

代码语言:javascript
复制
URI newUri = request.getUriInfo().getRequestUriBuilder().scheme("https").build();
URI baseUri = request.getUriInfo().getBaseUriBuilder().scheme("https").build();
request.setRequestUri(baseUri, newUri);
票数 1
EN

Stack Overflow用户

发布于 2016-08-28 09:19:19

如果使用Jetty,则可以通过向服务器注册org.eclipse.jetty.server.ForwardedRequestCustomizer来避免黑客攻击。这将查看构建基本URI的X-Forwarded-*头。

使用嵌入式Jetty的示例:

代码语言:javascript
复制
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});

无论您是否支持反向代理,这似乎都是可行的,所以我不知道为什么它不是默认启用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34862344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档