发出HTTP请求时,Go是否可以通过某种方式将DefaultNetworkCredentials与代理一起使用?

时间:2020-10-22 16:29:03

标签: go http-proxy ntlm defaultnetworkcredentials

我正在编写一个简单的Go实用程序,该实用程序向Internet发出一些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)
}

我一直找不到与CSharp的https://docs.microsoft.com/en-us/dotnet/api/system.net.credentialcache.defaultnetworkcredentials?view=netcore-3.1等效的Go。我找到了https://github.com/Azure/go-ntlmssp,但这需要我对用户的凭据进行硬编码,而我没有,并且我需要为每个用户编译一个新的二进制文件,而我不想这样做。我正在寻找0配置解决方案。我希望这是尽可能动态的。如果CSharp可以做到,为什么不能去?

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

有人告诉我可以使用WinHTTP或WinInet实现此目的。我将使用golang.org/x/sys/windows包,并从DLL中调用过程。另外,有人告诉我可以使用github.com/go-ole/go-ole并通过COM对象使用WinHTTP,就像在另一个SO问题:Windows system credentials in Go HTTP NTLM requests中一样。

更新:我最终决定选择WinInet,并创建了自己的程序包(gitlab.com/mjwhitta/win/wininet),其中包含可用于发出GET和POST请求的http.Client。有关如何使用自述文件的示例,请参见自述文件。如果将来有需要,我可能会对此进行扩展。欢迎请求请求。

最新消息:男孩,我觉得很蠢。 WinInet不会为您做NTLM ...所以我将其移植到WinHttp(gitlab.com/mjwhitta/win/winhttp)。