Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
golang与fastcgi如何读取远程用户_Go_Fastcgi_Basic Authentication_Openbsd - Fatal编程技术网

golang与fastcgi如何读取远程用户

golang与fastcgi如何读取远程用户,go,fastcgi,basic-authentication,openbsd,Go,Fastcgi,Basic Authentication,Openbsd,简短:如何使用fastcgi读取golang上的CGI var远程用户 长: 我正试图在一个httpd后面使用fcgi通过套接字编写一个go-to-work程序。httpd执行ssl终止并提供基本身份验证。我需要读取$REMOTE_USER,但我不能在golang中读取,而我可以在perl中读取 我的代码基于。我试着 但是authok总是false,user和pass仍然为空,尽管我确信授权(由httpd完成)是正确的。为了消除其他错误,我使用了perl: my $socket = FCGI::

简短:如何使用fastcgi读取golang上的CGI var远程用户

长: 我正试图在一个httpd后面使用fcgi通过套接字编写一个go-to-work程序。httpd执行ssl终止并提供基本身份验证。我需要读取$REMOTE_USER,但我不能在golang中读取,而我可以在perl中读取

我的代码基于。我试着

但是authok总是false,user和pass仍然为空,尽管我确信授权(由httpd完成)是正确的。为了消除其他错误,我使用了perl:

my $socket = FCGI::OpenSocket("/run/fcgi-check.sock", 5);
my $q = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, $socket);

while ($q->Accept() >= 0) {
    my $c = CGI::Simple->new;
    my $user_id      = $c->remote_user(); 
它在perl中运行良好

为了调试,我打印了r.Header的输出,得到:

map[Authorization:[]
go看到的标题中没有任何关于授权的信息,对吗?但在perl中是这样的

下面是一个完整但最小的golang代码示例,演示了该问题(在OpenBSD 5.8上,go版本为go1.4.2 OpenBSD/amd64,在httpd.conf中使用“authenticate”/“with restricted_users”)

package main

import (
        "github.com/gorilla/mux"
        "io"
        "log"
        "fmt"
        "net"
        "net/http"
        "net/http/fcgi"
)


func homeView(w http.ResponseWriter, r *http.Request) {
        headers := w.Header()
        headers.Add("Content-Type", "text/html")
        headers.Add("Cache-Control", "no-cache, no-store, must-revalidate")
        headers.Add("Pragma", "no-cache")
        headers.Add("Expires", "0")
        r.ParseForm()

        user, pass, authok := r.BasicAuth()

        if authok {
                io.WriteString(w, fmt.Sprintln("Auth OK"))
                io.WriteString(w, fmt.Sprintln("user is: "+user+", pass is: "+pass))
        } else {
                io.WriteString(w, fmt.Sprintln("Auth NOT OK"))
        }
}

func main() {

        r := mux.NewRouter()
        r.HandleFunc("/check/", homeView)

    var err error
        listener, err := net.Listen("unix", "/run/fcgi-check.sock")
        if err != nil {
                log.Fatal(err)
        }
        defer listener.Close()

        err = fcgi.Serve(listener, r)
        if err != nil { log.Fatal(err)}
}
谢谢你的帮助

提前谢谢!
T.

虽然
@JimB
关于你的方法是错误的这一点是正确的,但我将回答前面提到的问题

net/http/fcgi
包使用
net/http/cgi
的机制来填充
http.Request
的实例,该实例在FastCGI会话(调用)期间通过Web服务器提交的“参数”(键/值对)传递给处理程序。 这已经完成了

现在,如果您进行检查,您将看到未映射到http.Request的特定专用字段的变量

这意味着,您的代码应该能够使用如下方式访问所需的变量


更新2015-12-02:
@JimB
和OP进行的研究表明,显然无法读取FastCGI下的
远程用户
变量。很抱歉发出噪音。

简单的答案(从go版本1.4.2开始)go目前不支持CGI变量远程用户的传输。

这到fcgi包正在审查中,即将合并。如果它与您不再相关,希望它对其他人有用。

go 1.9将公开CGI环境变量。如此关闭的票据中所示:


您的perl示例使用的是REMOTE_USER变量,而Go示例则尝试使用BasicAuth。您是否检查了“REMOTE USER”的请求头(我相当确定CGI变量已被规范化并映射到头)还有,你为什么要使用FCGI?我找不到如何读取go中的远程用户CGI环境变量(如果
r.BasicAuth()
不是正确的方法)。正如我在帖子中所说,我已经使用
io.WriteString打印了完整的标题。WriteString(w,fmt.Sprintf(“Header:%s”,r.Header))
确认了授权:[]map是空的,并且在该标头中没有远程用户。我被卡住了。(还有一些我无法在此讨论的原因迫使我使用fcgi。)您尝试使用
r.BasicAuth()的操作
是不正确的,因为读取
REMOTE\u USER
CGI变量意味着身份验证将由web服务器执行,而您对其没有控制权。因此,您需要的是正确读取此变量的值。我已经提供了如何执行此操作的答案。它看起来不像
REMOTE\u USER
在fcgi包中使用。我会让进行身份验证的Web服务器将其放在标题或
HTTP\u REMOTE\u USER
变量中。@JimB:谢谢澄清。虽然修改Web服务器以解决go中的问题不太吸引人。实际上,现在看看cgi/fcgi代码,我认为REMOTE\u用户不会被转移到Go请求。只有少数特定变量,以及那些以
HTTP\uuu
开头的变量被添加到头中。@kostix:我已经检查并伪造了
r.Header.Get(“远程用户”)
。这不起作用,至少在golang版本1.4.2(OpenBSD 5.8的pgk)中不起作用。(正如我在原始问题中提到的(引用:“为了调试,我打印了r.Header的输出。”)@JimB:我想你是对的。Golang没有将远程用户转移到go请求中。@user208383,太糟糕了。我认为这是一个错误。很抱歉用我的答案误导你。在Linux/amd64下,通过go 1.5验证,Apache2.4.10+
mod_fcgid
+
mod_auth_basic
+
mod_authz_用户
go 1.9已经退出,并且它确实暴露了确实是远程用户。
package main

import (
        "github.com/gorilla/mux"
        "io"
        "log"
        "fmt"
        "net"
        "net/http"
        "net/http/fcgi"
)


func homeView(w http.ResponseWriter, r *http.Request) {
        headers := w.Header()
        headers.Add("Content-Type", "text/html")
        headers.Add("Cache-Control", "no-cache, no-store, must-revalidate")
        headers.Add("Pragma", "no-cache")
        headers.Add("Expires", "0")
        r.ParseForm()

        user, pass, authok := r.BasicAuth()

        if authok {
                io.WriteString(w, fmt.Sprintln("Auth OK"))
                io.WriteString(w, fmt.Sprintln("user is: "+user+", pass is: "+pass))
        } else {
                io.WriteString(w, fmt.Sprintln("Auth NOT OK"))
        }
}

func main() {

        r := mux.NewRouter()
        r.HandleFunc("/check/", homeView)

    var err error
        listener, err := net.Listen("unix", "/run/fcgi-check.sock")
        if err != nil {
                log.Fatal(err)
        }
        defer listener.Close()

        err = fcgi.Serve(listener, r)
        if err != nil { log.Fatal(err)}
}
ruser := r.Header.Get("Remote-User")