2015-11-30 2 views
2

Краткая: Как я могу прочитать CGI var REMOTE_USER на golang, используя fastcgi?golang with fastcgi как читать REMOTE_USER

Long: Я пытаюсь написать программу, чтобы перейти к работе за httpd, используя fcgi через сокет. Httpd выполняет ssl-окончание и предоставляет базовый auth. Мне нужно прочитать $ REMOTE_USER, но я не могу в golang, пока я могу в perl.

Мой код основан на this fcgi example. Я стараюсь

func homeView(w http.ResponseWriter, r *http.Request) {  
    user, pass, authok := r.BasicAuth() 

Но authok всегда ложно, пользователь и пропуск остается пустым, хотя я знаю, что разрешение (сделано 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:[] 

я прав, что заголовок, который видит идти не делает занимать какую-либо информацию о каких-либо разрешений? Но это происходит в perl.

Вот пример кода полный, но минимальный golang, который демонстрирует проблему (на OpenBSD 5.8 с версии идут go1.4.2 OpenBSD/amd64 и OpenBSDs HTTPd с «аутентификации„/“с restricted_users» в httpd.conf.

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)} 
} 

Помощь будут оценены!

Спасибо заранее! Т.

+1

Ваш Perl пример использует переменную REMOTE_USER, но пример Go пытается сделать BasicAuth. Вы проверили заголовки запроса для «Удаленного пользователя» (я уверен, что переменные CGI получаются каноническими и сопоставляются с заголовками)? Кроме того, почему вы используете FCGI? – JimB

+0

Я не могу найти, как читать переменную среды REMOTE_USER CGI в go (если 'r.BasicAuth()' не подходит для этого). Как сказано в моей публикации, я напечатал полные заголовки с помощью 'io.WriteString (w, fmt.Sprintf (« Заголовок:% s », r.Header)), подтвердил, что _Authorization: [] _ ​​карта пуста и нет _REMOTE_USER_ в этом заголовке. Я застрял. (И есть причины, по которым я не могу здесь обсуждать, что вынуждает меня использовать fcgi.) – user208383

+0

Ваша попытка использовать 'r.BasicAuth()' неверна просто потому, что чтение переменной CGI REMOTE_USER означает * ожидается, что аутентификация будет выполнена веб-сервером *, и вы не контролируете его. Так что вам нужно просто правильно прочитать значение этой переменной. Я дал ответ о том, как это сделать. – kostix

ответ

1

Простой ответ (начиная с версии 1.4.2) заключается в том, что go в настоящее время не поддерживает передачу переменной CGI REMOTE_USER.

+0

Проверено с помощью Go 1.5 под Linux/amd64, Apache2 2.4.10 + 'mod_fcgid' +' mod_auth_basic' + 'mod_authz_user' – kostix

+0

Go 1.9 сделает это: https://tip.golang.org/doc/go1.9#net/http/fcgi – luca76

1

Хотя @JimB правильно на том, что вы не правы в своем подходе, я буду отвечать на вопрос, как указано.

net/http/fcgi пакет использует аппарат net/http/cgi для заполнения экземпляра http.Request —, который передается в обработчик — с «параметрами» (пар ключ/значение), представленных на веб-сервер во время сеанса FastCGI (вызова). Это делается here.

Теперь, если вы проверите the relevant bit of the net/http/cgi code, вы увидите, что переменные, которые не привязаны к определенным выделенным полям http.Requestget converted to HTTP "headers".

Это означает, что ваш код должен иметь возможность доступа к переменной вам нужно использовать что-то вроде

ruser := r.Header.Get("Remote-User") 

Update 2015-12-02: в Reseach исполнении @JimB и ФП показал, что есть по-видимому, нет возможности читать переменную REMOTE_USER в FastCGI. Извините за шум.

+0

@JimB, спасибо, исправлено. – kostix

+0

На самом деле, глядя теперь на код cgi/fcgi, я не думаю, что REMOTE_USER будет вообще передан в запрос Go. В заголовки добавляются только несколько конкретных переменных, а также те, которые начинаются с 'HTTP_'. – JimB

+0

@kostix: Я проверил и фальсифицировал 'r.Header.Get (« Remote-User »)'. Это не работает, по крайней мере, не в версии golang 1.4.2 (pgk OpenBSD 5.8). (Как я уже упоминал в своем первоначальном вопросе (Цитата: «Чтобы отладить, я напечатал вывод r.Header»).) @JimB: Я думаю, что вы правы. Golang не передает REMOTE_USER в запрос go. – user208383

1

Этот core change пакет fcgi находится в поле зрения и близок к объединению.Если это уже не относится к вам, мы надеемся, что это будет полезно для других.

1

Go 1.9 будет выставлять переменные среды cgi. Как видно из этого замкнутого билета:

https://go-review.googlesource.com/c/40012

+1

Go 1.9 вышел, и он действительно разоблачает 'REMOTE_USER'. –

 Смежные вопросы

  • Нет связанных вопросов^_^