Есть ли в Go способ использования DefaultNetworkCredentials с прокси-сервером при выполнении HTTP-запроса?

Я пишу простую утилиту Go, которая делает несколько POST-запросов в Интернет, но мне нужно пройти через прокси и использовать NTLM, не зная учетных данных пользователя. Я видел код CSharp, как показано ниже:

wc = new CookieWebClient();
wc.UseDefaultCredentials = true;
wc.Proxy = WebRequest.DefaultWebProxy;
wc.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;

В Go мне удалось определить системный прокси с помощью взлома:

import (
    "net/http"
    "net/url"
    "strings"

    "golang.org/x/sys/windows/registry"
)

func getSystemProxy() func(req *http.Request) (*url.URL, error) {
    var e error
    var k registry.Key
    var proxy *url.URL
    var v string

    // Open the "Internet Settings" registry key
    k, e = registry.OpenKey(
        registry.CURRENT_USER,
        strings.Join(
            []string{
                "Software",
                "Microsoft",
                "Windows",
                "CurrentVersion",
                "Internet Settings",
            },
            "\\",
        ),
        registry.QUERY_VALUE,
    )
    if e != nil {
        return http.ProxyFromEnvironment
    }
    defer k.Close()

    // Read the "ProxyServer" value
    v, _, e = k.GetStringValue("ProxyServer")
    if (e != nil) || (v == "") {
        return http.ProxyFromEnvironment
    }

    // Get the http= portion and fix it up
    v = strings.Split(v, ";")[0]
    v = strings.Replace(v, "=", "://", 1)

    // Parse url
    if proxy, e = url.Parse(v); e != nil {
        return http.ProxyFromEnvironment
    }

    return http.ProxyURL(proxy)
}

Мне не удалось найти Go-эквивалент https://docs.microsoft.com/en-us/dotnet/api/system.net.credentialcache.defaultnetworkcredentials?view=netcore-3.1. Я нашел https://github.com/Azure/go-ntlmssp, но для этого мне нужно чтобы жестко закодировать учетные данные пользователя, которых у меня нет, и мне нужно будет скомпилировать новый двоичный файл для каждого пользователя, чего я не хочу делать. Я ищу решение конфигурации 0. Я бы предпочел, чтобы это было как можно более динамичным. Если CSharp может это сделать, почему не может Go?

Любая помощь будет принята с благодарностью!


person mjwhitta    schedule 22.10.2020    source источник
comment
Вам нужно создать двоичный файл для каждого пользователя только в том случае, если вы решите жестко закодировать значения. Вы можете так же легко получить их из CLI, переменных среды или файлов конфигурации. Ничто в этой библиотеке не требует жесткого ввода учетных данных.   -  person Adrian    schedule 22.10.2020
comment
Верно, но я думаю, что собирался использовать 0 config. Я должен иметь возможность передать его пользователю, и он должен просто работать. Я могу сделать это с помощью CSharp. Я надеялся использовать Go.   -  person mjwhitta    schedule 22.10.2020
comment
Посетите github.com/Azure/go-ntlmssp.   -  person Erkin Djindjiev    schedule 24.10.2020
comment
@ErkinDjindjiev: У меня есть. Эта ссылка в моем вопросе выше. Это не работает. Я не знаю учетных данных пользователя, и я искал ответ конфигурации 0. Сначала я использовал WinHTTP, и это сработало очень хорошо. С тех пор я переключился на WinInet для своего окончательного ответа.   -  person mjwhitta    schedule 24.10.2020


Ответы (1)


Мне сказали, что для этого я могу использовать WinHTTP или WinInet. Я поиграю с пакетом golang.org/x/sys/windows и вызову процедуры из DLL. В качестве альтернативы мне сказали, что я могу использовать github.com/go-ole/go-ole и использовать WinHTTP через COM-объекты, как в этом другом вопросе SO: Системные учетные данные Windows в запросах Go HTTP NTLM.

Обновление: в конечном итоге я решил остановиться на WinInet и создал свой собственный пакет (gitlab.com/mjwhitta/win/wininet), который содержит http.Client, который можно использовать для выполнения запросов GET и POST. См. README для примера того, как его использовать. Я, вероятно, расширим его в будущем, если у меня возникнет необходимость. Запросы на вытягивание приветствуются.

Последнее обновление: Боже, я чувствую себя глупо. WinInet не собирается выполнять NTLM за вас... поэтому я портировал его на WinHttp (gitlab.com/mjwhitta/win/winhttp).

person mjwhitta    schedule 22.10.2020