这是我想要实现的结果:

  • 客户端浏览器(在我的情况下为Chrome)在50070上命中Apache HTTPd服务器(server1) . 客户端浏览器无法访问Kerberos KDC并且不携带Kerberos / GSS身份验证数据 .

  • Apache HTTPd可以访问KDC并配置为需要Kerberos身份验证,但是使用密码回退(即 KrbMethodK5PasswdOn ,因此它在HTTP标头中接受“ Authorization: Basic ”) .

  • 由于备用选项,客户端浏览器会提示用户输入登录名和密码(因为客户端没有提供Kerberos票证) . Apache HTTPd根据Kerberos验证提供的登录名和密码,并获取正确的用户主体Kerberos票证并将其保留在内存中(由于 KrbSaveCredentials 选项,它还将其保存到/ tmp) .

  • Apache HTTPd反向代理到后端服务器(server2),后端服务器也侦听端口50070.后端服务器正在运行Jetty,它只接受Kerberos,没有任何密码/基本身份验证回退 - 如果没有Kerberos票证,则没有条目 . Apache HTTPd使用登录传递将来自KDC的用户主体Kerberos票证发送到server2 .

在我当前的配置中,第1,2和3点成功运行 - 即客户端到server1身份验证正常工作,我可以看到Apache在server1上保存用户主要票证一小段时间 .

但是,我很难强制Apache HTTPd使用获取的用户Kerberos票证来对server2进行身份验证 . 基本上,根本不会向server2发送任何身份验证详细信息 .

这是我的配置:

<VirtualHost 1.2.3.4:50070>
  ServerAlias server1.example.com:50070
  ServerAlias server1:50070
  ProxyPreserveHost Off
  ProxyRequests Off
  ProxyPass / http://server2.example.com:50070/ retry=0
  ProxyPassReverse / http://server2.example.com:50070/ retry=0
  <Proxy *>
    Order allow,deny
    Allow from all
  </Proxy>
  ErrorLog logs/error_log
  TransferLog logs/access_log
  LogLevel debug
  <Location />
    Options None
    AuthType Kerberos
    AuthName "NameNode"
    KrbMethodNegotiate on
    KrbMethodK5Passwd on
    KrbServiceName HTTP
    KrbAuthRealms EXAMPLE.COM
    Krb5Keytab /etc/httpd/conf/http.keytab
    KrbSaveCredentials on
    KrbLocalUserMapping on
    Require valid-user
  </Location>
</VirtualHost>

我也尝试使用 mod_proxy_http 提供的 SetEnv proxy-chain-auth ,我认为它按设计工作,确实发送了“ Authorization: Basic ... " header that client came to server1 with, onward to server2, but server2 does not support anything but Kerberos (i.e. " Authorization: Negotiate ”的确切内容,并在其日志中抱怨未知的auth方法 .

有没有办法强制Apache HTTPd使用从KDC获得的Kerberos票证,使用客户端浏览器提供的登录名和密码,然后使用Negotiate方法(带票证)与目标服务器2进行身份验证我反向代理?