当前位置: 首页 > 知识库问答 >
问题:

在Tomcat中为http端口获取相应的https端口号

滕璞瑜
2023-03-14

我试图最小化我的webapp的配置,我要删除的事情之一是端口号映射:

  • http:80-

因为配置已经存在于conf/server中。xml,我不想在我的应用程序中重复这些设置。必须更改(并记住更改)多个配置文件是一种痛苦。此外,只要应用程序支持http和https,就不应该关心它部署到了什么环境/容器中。

我在我的网站上配置了以下内容。xml,但除了重定向之外,我还需要能够构建https URL:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>secure</web-resource-name>
        <url-pattern>/https/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

上面的块告诉servlet容器将http请求重定向到它的https对应方。显然,Tomcat知道请求来自哪个连接器,并在服务器中查找“redirectPort”属性。xml,并使用它构建https URL。

根据这些先前/相关的问题,似乎没有一个标准或tomcat特定的方法来获取请求的相应https端口:

  • Tomcat:如何在Java中获取安全端口号
  • 获取HTTPS的JSP页面的服务器名称和端口号

TL;DR:我的问题是,你有什么想法来获取不安全请求的对应https端口号,而不在你的webapp中明确配置它们

我的一个想法是,使用与当前请求相同的端口号,从webapp向自身发出http调用,到达安全约束后面的路径,并从响应中解析重定向位置。当然,应该缓存响应。有没有更直接的方法?

编辑:添加了一个带有想法代码的答案。

共有2个答案

黄宏大
2023-03-14

我不明白你为什么需要知道安全端口号。如果被访问的资源被标记为需要SSL,Tomcat将向https:和相应的安全端口发送重定向。这就是服务器中的配置。xml是为。

邵华皓
2023-03-14

如果有人想知道如何实现我在问题中提出的想法,这里有一些我放在一起测试它的示例代码。不过,我不认为我会采用这种解决方案。

这与问题主体中的安全约束块一起工作。

private static final String HTTPS_CONSTRAINED_PATH = "/https";

private static ConcurrentHashMap<String, Integer> resolvedHttpsPortMap = new ConcurrentHashMap<String, Integer>();
private static final ReentrantLock portMapLock = new ReentrantLock();

public static int resolveHttpsPort(HttpServletRequest request) {
    if (request.isSecure()) return request.getServerPort();
    String key = request.getServerName() + ":" + request.getServerPort();
    Integer port = resolvedHttpsPortMap.get(key);
    if (port == null) {
        portMapLock.lock();
        try {
            port = resolvedHttpsPortMap.get(key);
            if (port == null) {
                URL url = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath() + HTTPS_CONSTRAINED_PATH);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                if (conn.getResponseCode() != 301 && conn.getResponseCode() != 302
                        && conn.getResponseCode() != 303 && conn.getResponseCode() != 307) {
                    throw new IllegalStateException("Got unexpected response code " + conn.getResponseCode() + " from URL: " + url);
                }
                String location = conn.getHeaderField("Location");
                if (location == null) {
                    throw new IllegalStateException("Did not get a Location header in the response from URL: " + url);
                }
                URL locationUrl = new URL(location);
                port = locationUrl.getPort();
            }
        } catch (Exception e) {
            logger.warn("Could not determine corresponding HTTPS port for '" + key + "'", e);
        } finally {
            if (port == null) port = -1;
            resolvedHttpsPortMap.put(key, port);
            portMapLock.unlock();
        }
    }
    return port;
}
 类似资料:
  • http/https 端口与 ws端口 冲突吗?

  • 我正在尝试在Centos tomcat7上托管一个网站,如果我在端口80上运行tomcat7,一切正常,即74.208.164.45,但如果我想使用https://74.208.164.45/,它不起作用,但如果我这样尝试https://74.208.164.45:8443/添加密钥库之后,它就可以正常工作了。 所以,我需要一种在80和https上运行tomcat的方法,即https://74.2

  • 我想创建一个 angular.io 应用程序,但其余的API应从不同的服务器端付。 来自localhost的角度内容:4200,来自node express服务器的数据在localhost上独立启动:3000。但是当我注入并使用‘http’时,如何配置要使用的端口?

  • 问题内容: 我在jboss容器(相同的Unix框)中部署了两个应用程序。如果我收到来自app1的请求,则需要对app2提出相应的请求。 例如: 如果app1请求为:http : //example.com/context? param1=123, 那么我需要提取“ http://example.com/ ”,以便可以对第二个应用程序提出请求。 我尝试使用: 方法,但请求可能来自http或https

  • 问题内容: 我需要获取机器上所有打开的端口以及打开它们的应用程序的列表。我需要以编程方式获取此信息。 谢谢。 问题答案: 我希望能有一个更聪明的答案。我只是这样做(用Python编程),试图重写一个名为NetHogs的程序。我的版本在这里,特别是这里是Python中用于从中解析表的模块。如果您不是精通Python的人(请学习它),那么请看一下原始的NetHogs,它使用了C / C ++的混合(阅

  • 我有一个部署在Glassfish上的应用程序,并侦听端口8181以获取HTTPS流量(当前)。问题是在部署时,客户很少为服务器创建有效证书。这意味着HTTPS无法通过证书检查。 在我们的应用程序中,我们希望通过HTTP获取某些类型的内容,因为它是静态的,并且获取未加密这一事实不是问题。 我们确实存在的问题是,只有端口8181可供用户使用(防火墙等不能更改)。 因此,我们需要一种方法让Glassfi