英文:
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函数
func (*Request) BasicAuth
从请求的Authorization头部获取用户名,但是使用Authorization头部的Negotiate方式就不行了。此外,我无法使用REMOTE_USER环境变量,因为没有CGI环境。我还尝试设置RequestHeader,但没有成功。
有没有办法从Go应用程序中获取经过授权的用户名?
英文:
I'm using Apache as reverse proxy for things like authentication in front of the go http server.
The following apache kerberos setup works with one problem. I don't know how to get the authenticated username in my go application.
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>
With
AuthType basic
I get the username from the request's Authorization header with the go function
func (*Request) BasicAuth
but with Authorization header negotiate this is not possible. Furthermore I'm not able to use the REMOTE_USER environment variable because there is no cgi environment. I also tried to set the RequestHeader but without any success.
Is there any possibility to get the authorized username from the go application?
答案1
得分: 5
抱歉耽搁了一下,我之前忙于其他项目。非常感谢您的建议。在切换到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")
英文:
Sorry for the delay - I was involved in other projects. Many thanks for the suggestions. The following solution now works for me after switching to the environment 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>
The user can be accessed in Go with:
user := req.Header.Get("X-Forwarded-User")
答案2
得分: 1
请不要使用重写解决方法,因为如果使用类似mod_authn_ntlm(ntlm与本地计算机)的模块设置了REMOTE_USER,您将在执行阶段遇到问题(请参阅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}
英文:
do NOT use the rewrite workaround, because you will get into trouble with execution phases if the REMOTE_USER is set with a module like mod_authn_ntlm (ntlm with local computer, see https://support.microsoft.com/en-us/kb/896861).
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule . - [E=RU:%1]
RequestHeader set X-Remote-User %{RU}e
instead use the following method:
RequestHeader set X-Remote-User expr=%{REMOTE_USER}
答案3
得分: 0
你可以通过SetEnvIf
来设置一个头部 - http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html#setenvif - 如下所示:
SetEnvIf Authorization "(.*)" HTTP_APP_USER=$1
然后你可以通过r.Header.Get("HTTP_APP_USER")
在Go中访问它。
请注意,不能保证客户端没有同时设置相同的头部:http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#x-headers
> 在使用这些头部时要小心,因为如果原始请求已经包含了这些头部,它们将包含多个(逗号分隔的)值。例如,你可以在源服务器的日志格式字符串中使用%{X-Forwarded-For}i
来记录原始客户端的IP地址,但如果请求通过多个代理,你可能会得到多个地址。
英文:
You should be able to set a header via SetEnvIf
- http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html#setenvif - as below:
SetEnvIf Authorization "(.*)" HTTP_APP_USER=$1
You can then access it in Go via r.Header.Get("HTTP_APP_USER")
.
Beware that there's no guarantee the client hasn't also set a header with the same: 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.
答案4
得分: 0
尝试以下配置,然后您应该在头部的X-Forwarded-User
中看到您的用户名。确保已加载头部模块,例如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>
英文:
Try the following config, you should then see your username in the header X-Forwarded-User
. Make sure the headers module is loaded e.g. 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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论