Apache,mod_auth_kerb,mod_proxy:在 Go Web 应用程序中获取经过身份验证的用户

Apache, mod_auth_kerb, mod_proxy: Get authenticated user in Go Web Application

我使用 Apache 作为反向代理,用于在 go http 服务器前面进行身份验证。

以下 apache kerberos 设置适用于一个问题。我不知道如何在我的 go 应用程序中获取经过身份验证的用户名。

httpd.conf:

<VirtualHost host.domain.com:80>
  ProxyPreserveHost On
  ProxyPass / http://127.0.0.1:9000/
  ProxyPassReverse / http://127.0.0.1:9000/

  <Location />
    ## gzip
    ##
    AddOutputFilterByType DEFLATE text/html

    Order                      deny,allow
    Allow                      from all

    AuthType                   Kerberos
    AuthName                   "User Admin"
    KrbAuthRealms              DOMAIN.COM
    Krb5Keytab                 /etc/host.krb5keytab
    KrbMethodNegotiate         on
    KrbAuthoritative           on
    KrbMethodK5Passwd          off
    KrbLocalUserMapping on
    KrbSaveCredentials         on
    require valid-user
  </Location>
</VirtualHost>

 AuthType                    basic

我使用 go 函数

从请求的授权 header 中获取用户名
func (*Request) BasicAuth

但通过授权 header 协商这是不可能的。此外,我无法使用 REMOTE_USER 环境变量,因为没有 cgi 环境。我也尝试设置 RequestHeader 但没有成功。

是否有可能从 go 应用程序中获取授权用户名?

您应该可以通过 SetEnvIf - http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html#setenvif - 设置 header - 如下所示:

SetEnvIf Authorization "(.*)" HTTP_APP_USER=

然后您可以通过 r.Header.Get("HTTP_APP_USER") 在 Go 中访问它。

请注意,不能保证客户端没有设置一个header相同的:http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#x-headers

Be careful when using these headers on the origin server, since they will contain more than one (comma-separated) value if the original request already contained one of these headers. For example, you can use %{X-Forwarded-For}i in the log format string of the origin server to log the original clients IP address, but you may get more than one address if the request passes through several proxies.

尝试以下配置,然后您应该会在 header X-Forwarded-User 中看到您的用户名。确保 headers 模块已加载,例如a2enmod headers:

<VirtualHost host.domain.com:80>

  <Location />
    ## gzip
    ##
    AddOutputFilterByType DEFLATE text/html

    AuthType                   Kerberos
    AuthName                   "User Admin"
    KrbAuthRealms              DOMAIN.COM
    Krb5Keytab                 /etc/host.krb5keytab
    KrbMethodNegotiate         on
    KrbAuthoritative           on
    KrbMethodK5Passwd          off
    KrbLocalUserMapping        on
    KrbSaveCredentials         on
    require valid-user
    RequestHeader              set X-Forwarded-User %{REMOTE_USER}s    
  </Location>

  ProxyPreserveHost On
  ProxyPass / http://127.0.0.1:9000/
  ProxyPassReverse / http://127.0.0.1:9000/

</VirtualHost>

抱歉耽搁了 - 我正在参与其他项目。非常感谢您的建议。切换到环境 CentOS 7/httpd 2.4 后,以下解决方案现在适用于我:

<VirtualHost host.domain.com:80>

  <Location />
    ## gzip                                                                                          
    ##                                                                                               
    AddOutputFilterByType DEFLATE text/html

    AuthType                   Kerberos
    AuthName                   "Web Application"
    KrbAuthRealms              DOMAIN.COM
    Krb5Keytab                 /etc/host.krb5keytab
    KrbMethodNegotiate         on
    KrbAuthoritative           on
    KrbMethodK5Passwd          off
    KrbLocalUserMapping        on
    KrbSaveCredentials         on
    require valid-user

    RequestHeader unset X-Forwarded-User
    RewriteEngine On
    RewriteCond %{LA-U:REMOTE_USER} (.+)
    RewriteRule .* - [E=RU:%1]
    RequestHeader add X-Forwarded-User %{RU}e
  </Location>

  ProxyPreserveHost On
  ProxyPass / http://127.0.0.1:8000/
  ProxyPassReverse / http://127.0.0.1:8000/

  ServerName host.domain.com
 </VirtualHost>

可以在 Go 中访问用户:

user := req.Header.Get("X-Forwarded-User")

不要使用重写解决方法,因为如果 REMOTE_USER 设置为类似 mod_authn_ntlm 的模块(本地计算机的 ntlm,请参阅 https://support.microsoft.com/en-us/kb/896861).

RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule . - [E=RU:%1]
RequestHeader set X-Remote-User %{RU}e

改为使用以下方法:

RequestHeader set X-Remote-User expr=%{REMOTE_USER}