访问Wildfly管理控制台时出现错误 - 需要身份验证

3

我在登录Wildfly 13管理控制台后收到身份验证要求错误。

如果我输入的用户名或密码错误,它会再次要求输入,但如果我输入正确,它会显示带有错误消息的页面(因此我认为用户名和密码是正确的,但之后发生了其他错误)。

enter image description here

我正在使用 Docker 运行 Nginx 和 Wildfly 容器。Nginx 在外部监听端口 9991 并代理请求给 Wildfly 容器,但是在访问 Wildfly 控制台时出现了错误。这个错误仅仅发生在 Wildfly 控制台上,其他请求包括代理到 WebSocket 或 Wildfly 8080 端口的请求都成功完成。Wildfly 容器监听外部端口 9990,我可以通过此端口成功访问控制台。如果在 Docker 中映射端口 "9992:9990",我仍然可以通过端口 9992 成功访问控制台。因此,似乎这与 Docker 无关,而是与 Wildfly 控制台本身相关。可能是某种身份验证在使用反向代理时未能成功完成。请注意保留 HTML 标签。
我有一个演示docker项目https://github.com/lucasbasquerotto/pod/tree/0.0.6,您可以下载标签0.0.6,其中已经设置好了与Wildfly 13和nginx的工作,并模拟此错误。
git clone -b 0.0.6 --single-branch --depth 1 https://github.com/lucasbasquerotto/pod.git
cd pod
docker-compose up -d

然后,如果您使用用户名monitor和密码Monitor#70365直接在http://localhost:9990访问容器,一切正常

但是,如果您使用相同的凭据通过nginx反向代理访问http://localhost:9991您将收到错误信息

我的nginx.conf文件:

upstream docker-wildfly {
  server wildfly:9990;
}

location / {
  proxy_pass         http://docker-wildfly;
  proxy_redirect     off;
  proxy_set_header   Host $host;
  proxy_set_header   X-Real-IP $remote_addr;
  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header   X-Forwarded-Host $server_name;
}

我也尝试过以下方式:

proxy_set_header   X-Forwarded-Proto $scheme;

同时,还需要使用授权头(Authorization header)(只需第二行和两者都需要):

proxy_set_header   Authorization $http_authorization;
proxy_pass_header  Authorization;

同时,还需要使用带有端口的主机头(而不仅仅是$host)进行定义:

proxy_set_header   Host $server_addr:$server_port;

我已经尝试了上述的单独和组合配置,但都没有成功。
有什么建议吗?
有人成功通过反向代理访问Wildfly控制台吗?
更新(2018-09-22)
看起来Wildfly使用摘要认证(而不是基本认证)。
我在控制台中看到以下头部:
Authorization: Digest username="monitor", realm="ManagementRealm", nonce="AAAAAQAAAStPzpEGR3LxjJcd+HqIX2eJ+W8JuzRHejXPcGH++43AGWSVYTA=", uri="/console/index.html", algorithm=MD5, response="8d5b2b26adce452555d13598e77c0f63", opaque="00000000000000000000000000000000", qop=auth, nc=00000005, cnonce="fe0e31dd57f83948"

我没有看到关于使用nginx代理传递带有摘要头的请求的文档(但我认为它应该是透明的)。

这里在SO上看到一个问题是https://serverfault.com/questions/750213/http-digest-authentication-on-proxied-server,但目前还没有答案。

我看到有nginx非官方模块https://www.nginx.com/resources/wiki/modules/auth_digest/,但在github存储库(https://github.com/atomx/nginx-http-auth-digest)中说:

ngx_http_auth_digest模块补充了Nginx内置的基本身份验证模块,提供对RFC 2617摘要身份验证的支持。该模块目前可用,但仅经过作者测试和审核。鉴于这是安全代码,一个人的视线几乎肯定不足以保证它是100%正确的。在一些错误报告出现并且代码中的一些“未知的未知”被排除之前,请将此模块视为“Alpha”并适当地对待它。
另外,在文件中硬编码用户和密码供nginx使用(在这种情况下,身份验证应对反向代理透明)似乎不太合适。
无论如何,我尝试了它,并且它正确地要求我进行身份验证,即使最终目标没有摘要身份验证,例如尝试连接到wildfly站点(而不是控制台),在尝试连接到nginx时(在代理请求之前),它会询问,然后成功转发到目标,除了wildfly控制台的情况,它会一直要求我进行身份验证。
因此,我认为这不是解决方案。问题似乎在于nginx传递给Wildfly Console的内容。
1个回答

1
我在HAL管理控制台v3.3和3.2中遇到了同样的问题。尽管页面提示http基本认证用户和密码,但我无法使ngnix HTTPS工作,因为出现了身份验证错误。
这是在同一服务器上的独立模式下测试的。
我的设置是: 外部(https)- > nginx - > http://halServer:9990/ 这导致https工作,但出现了HAL身份验证错误(在浏览器控制台中看到),网页是空白的。 在第一次访问时,网页通常会要求http基本认证凭据,但随后几乎所有https请求都会返回身份验证错误。
我通过首先使用自签名证书启用HAL控制台https,然后配置nginx代理传递给HAL HTTPS监听器来使其正确工作。
工作设置是: 外部(https)- > nginx(https)- > https://halServer:9993/
以下是ngnix配置。
server {
    listen                  80;
    listen                  [::]:80;
    listen                  443 ssl;
    listen                  [::]:443 ssl;
    server_name             halconsole.mywebsite.com;

    # SSL
    ssl_certificate         /keys/hal_fullchain.pem;
    ssl_certificate_key     /keys/hal_privkey.pem;
    ssl_trusted_certificate /keys/hal_chain.pem;

    # security
    include                 nginxconfig.io/security.conf;

    # logging
    access_log              /var/log/nginx/halconsole.mywebsite.com.access.log;
    error_log               /var/log/nginx/halconsole.mywebsite.com.error.log warn;

    # reverse proxy
    location / {
        # or use static ip, or nginx upstream
        proxy_pass https://halServer:9993;
        include    nginxconfig.io/proxy.conf;
    }

    # additional config
    include nginxconfig.io/general.conf;
    include nginxconfig.io/letsencrypt.conf;
}

# subdomains redirect
server {
    listen                  443 ssl;
    listen                  [::]:443 ssl;
    server_name             *.halconsole.mywebsite.com;

    # SSL
    ssl_certificate         /keys/hal_fullchain.pem;
    ssl_certificate_key     /keys/hal_privkey.pem;
    ssl_trusted_certificate /keys/hal_chain.pem;
    return                  301 https://halconsole.mywebsite.com$request_uri;
}

proxy.conf

proxy_http_version                 1.1;
proxy_cache_bypass                 $http_upgrade;

# Proxy headers
proxy_set_header Upgrade           $http_upgrade;
proxy_set_header Connection        $connection_upgrade;
proxy_set_header Host              $http_host;
proxy_set_header X-Real-IP         $remote_addr;
proxy_set_header Forwarded         $proxy_add_forwarded;
proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host  $host;
proxy_set_header X-Forwarded-Port  $server_port;
proxy_set_header X-Forwarded-By    $server_addr;

# Proxy timeouts
proxy_connect_timeout              60s;
proxy_send_timeout                 60s;
proxy_read_timeout                 60s;

启用https控制台最简单的方法是使用控制台本身

  1. 使用命令行keytool或GUI程序生成Java JKS密钥库。我喜欢GUI,所以我使用了Key Store Explorer https://github.com/kaikramer/keystore-explorer

  2. 将密钥库文件复制到halServer服务器上,该服务器具有读取权限(无需保密),我将其放在wildfly数据目录中的“keystore”目录中。

# your file paths might differ, don't copy paste
cp /home/someUser/sftp_uploads/managementKS /opt/wildfly/standalone/data/keystore/managementKS
  1. 设置权限
# your file paths might differ, don't copy paste
chown --recursive -H wildfly:wildfly /opt/wildfly/standalone/data/keystore
  1. (use vpn) login to cleartext console http://halServer:9990/

  2. add keystore : navigate :

     configuration -> subsystems -> security (elytron) -> other settings (click view button)
     stores -> keystore -> add
     ...
     Name = managementKS
     Type = JKS
     Path = keystore/managementKS
     Relative to = jboss.server.data.dir
     Credential Reference Clear Text = keystore-password click Add
    

在 standalone.xml 中的结果

<key-store name="managementKS">
    <credential-reference clear-text="keystore-password"/>
    <implementation type="JKS"/>
    <file path="keystore/managementKS" relative-to="jboss.server.data.dir"/>
</key-store>
  1. add key manager : navigate :

     ssl -> key manager -> add
     ...
     Name = managementKM
     Credential Reference Clear Text = keystore-password
     Key Store = managementKS
    

在 standalone.xml 中的结果

<key-manager name="managementKM" key-store="managementKS">
    <credential-reference clear-text="keystore-password"/>
</key-manager>
  1. add ssl context : navigate :

     ssl -> server ssl context -> add
     ...
     Name = managementSSC
     Key Manager = managementKM
     ...
     Edit added : Protocols = TLSv1.2
     save
    

在 standalone.xml 中的结果

<server-ssl-contexts>
    <server-ssl-context name="managementSSC" protocols="TLSv1.2" key-manager="managementKM"/>
</server-ssl-contexts>
  1. go back

     runtime -> server (click view button)
     http management interface (edit)
     set secure socket binding = management-https
     set ssl context = managementSSC
     save
    
  2. restart wildfly

     systemctl restart wildfly
    

谢谢你的回答!我目前没有使用管理控制台,而且我已经有一段时间没有使用Wildfly配置了,所以我无法测试你提出的建议。话虽如此,我认为它在我们的情况下不起作用,因为如果我没记错,问题甚至发生在非安全(http)环境中,所以我认为问题与密钥库无关(毕竟它有HTTP和HTTPS端口,允许非安全连接)。也许它可能与另一个配置相关,比如http_upgradeconnection_upgrade。无论如何,我对你详细的回答给予了+1的评价。 - Lucas Basquerotto
我的 nginx 版本: nginx/1.18.0 ;; 你尝试代理非安全的 http 到 hal 控制台的非安全 http 吗?但是没有成功吗? 在我的设置中,明文 http 总是可以工作的(例如:外部 http -> nginx -> http hal)。 - Andrei Matei
我不是完全确定,我在2018年设置并放弃使用控制台,所以我不记得确切的设置。如果我没记错的话,我尝试过 HTTPS -> Nginx(输入https->代理http)-> HAL(http)。当时,我将wildfly端口外部公开(而不经过nginx),它可以工作(但我更愿意在中间使用nginx)。 - Lucas Basquerotto
1
你在上一条评论中所描述的正是我所经历的。也就是说,直接在任何端口上暴露控制台,无论是http还是https都可以工作。像你一样,我也不喜欢http的想法,并希望通过nginx自动使用let's encrypt来完成https。场景:HTTPS-> Nginx(输入https->代理http)-> HAL(http),其中以http方式公开控制台无法工作,会返回身份验证错误。我通过使用https公开控制台并将nginx代理到https来解决了这个问题。也就是:HTTPS-> Nginx(输入https->代理https)-> HAL(https),其中HAL(https)使用自签名证书。 - Andrei Matei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接