Golang解析DNS消息时遇到无法反序列化的问题

Golang解析DNS消息时遇到无法反序列化的问题 尝试按照此处所述连接到 SharePoint,我能够获取到 security token,并且需要将其提交到 https://yourdomain.sharepoint.com/_forms/default.aspx?wa=wsignin1.0 以获取 access token

此请求的响应包含几个 Cookie,这些 Cookie 必须作为请求头传递给所有后续请求。它们由 Set-Cookie 标头标记。我们需要的是以 rtFa= 和 FedAuth= 开头的那些。访问令牌 Cookie 必须作为 Cookie 请求头包含在 https://yourdomain.sharepoint.com/_api/contextinfo 的 POST 请求中。

使用 Thunder client 我能够获取到这些 Cookie。

enter image description here

但是我无法通过我的 GO 代码获取它们,我尝试了如下方式:

            token := string(n.Content) // n.Content 从 XML 读取获得
			const mydomain = "https://domain.sharepoint.com/_forms/default.aspx?wa=wsignin1.0"
			resp2, err := http.Post(mydomain, "text/plain;charset=UTF-8", strings.NewReader(token))
			if err != nil {
				log.Fatal("error: ", err)
			}
			defer resp2.Body.Close()

			body2, _ := ioutil.ReadAll(resp2.Body)
			fmt.Println("response Body:", string(body2))

并得到如下输出:

2021/07/08 22:31:01 error: Post "https://domain.sharepoint.com/_forms/default.aspx?wa=wsignin1.0": dial tcp: lookup domain.sharepoint.com on 192.168.244.17:53: cannot unmarshal DNS message
exit status 1

更多关于Golang解析DNS消息时遇到无法反序列化的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang解析DNS消息时遇到无法反序列化的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


从错误信息看,这是一个DNS解析问题,而不是SharePoint认证问题。错误发生在DNS消息反序列化阶段,可能是DNS响应格式异常或网络问题导致的。

以下是处理DNS解析问题的示例代码:

package main

import (
    "context"
    "fmt"
    "net"
    "net/http"
    "time"
)

func main() {
    // 方法1:使用自定义DNS解析器
    customResolver := &net.Resolver{
        PreferGo: true,
        Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
            d := net.Dialer{
                Timeout: 10 * time.Second,
            }
            // 使用公共DNS服务器
            return d.DialContext(ctx, "udp", "8.8.8.8:53")
        },
    }
    
    dialer := &net.Dialer{
        Resolver: customResolver,
        Timeout:  30 * time.Second,
    }
    
    transport := &http.Transport{
        DialContext: dialer.DialContext,
    }
    
    client := &http.Client{
        Transport: transport,
        Timeout:   60 * time.Second,
    }
    
    // 方法2:直接使用IP地址(如果已知)
    // 或者使用net.LookupHost先解析域名
    addrs, err := net.LookupHost("domain.sharepoint.com")
    if err != nil {
        fmt.Printf("DNS lookup failed: %v\n", err)
        // 尝试备用DNS解析
        addrs, err = customResolver.LookupHost(context.Background(), "domain.sharepoint.com")
        if err != nil {
            fmt.Printf("Custom DNS lookup also failed: %v\n", err)
            return
        }
    }
    
    fmt.Printf("Resolved addresses: %v\n", addrs)
    
    // 使用自定义HTTP客户端发送请求
    token := "your_token_here"
    url := "https://domain.sharepoint.com/_forms/default.aspx?wa=wsignin1.0"
    
    req, err := http.NewRequest("POST", url, strings.NewReader(token))
    if err != nil {
        fmt.Printf("Request creation failed: %v\n", err)
        return
    }
    
    req.Header.Set("Content-Type", "text/plain;charset=UTF-8")
    
    resp, err := client.Do(req)
    if err != nil {
        fmt.Printf("Request failed: %v\n", err)
        return
    }
    defer resp.Body.Close()
    
    // 检查Cookie
    cookies := resp.Cookies()
    for _, cookie := range cookies {
        fmt.Printf("Cookie: %s=%s\n", cookie.Name, cookie.Value)
    }
    
    // 或者从Header直接读取
    setCookies := resp.Header["Set-Cookie"]
    for _, cookie := range setCookies {
        fmt.Printf("Set-Cookie: %s\n", cookie)
    }
}

如果问题持续存在,可以添加DNS调试信息:

// 启用DNS调试
func debugDNS() {
    // 设置环境变量来调试DNS
    // 在程序启动前设置:GODEBUG=netdns=go
    // 或者使用net包的内置功能
    
    // 检查系统DNS配置
    conf, err := net.LookupHost("domain.sharepoint.com")
    if err != nil {
        fmt.Printf("System DNS error: %v\n", err)
    }
    fmt.Printf("System DNS result: %v\n", conf)
    
    // 尝试不同的解析方法
    ctx := context.Background()
    
    // 使用自定义DNS服务器列表
    dnsServers := []string{"8.8.8.8:53", "1.1.1.1:53", "9.9.9.9:53"}
    
    for _, dnsServer := range dnsServers {
        resolver := &net.Resolver{
            PreferGo: true,
            Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
                d := net.Dialer{Timeout: 5 * time.Second}
                return d.DialContext(ctx, "udp", dnsServer)
            },
        }
        
        addrs, err := resolver.LookupHost(ctx, "domain.sharepoint.com")
        if err == nil {
            fmt.Printf("Success with DNS server %s: %v\n", dnsServer, addrs)
            break
        }
        fmt.Printf("Failed with DNS server %s: %v\n", dnsServer, err)
    }
}

对于SharePoint认证,获取Cookie的正确方式应该是:

// 创建带Cookie容器的客户端
jar, _ := cookiejar.New(nil)
client := &http.Client{
    Jar: jar,
    Timeout: 30 * time.Second,
}

// 发送请求后,Cookie会自动保存在jar中
resp, err := client.Post(url, "text/plain;charset=UTF-8", strings.NewReader(token))
if err != nil {
    // 处理错误
}

// 后续请求会自动携带Cookie
apiResp, err := client.Post(apiURL, "application/json", nil)

DNS反序列化错误通常表明DNS服务器返回了格式不正确的响应。使用自定义DNS解析器或更换DNS服务器可以解决这个问题。

回到顶部