วิธีโทร SOAP ใน Golang ผ่าน HTTPS

ฉันกำลังพยายามโทร SOAP ผ่าน https

ฉันได้ลองใช้ไลบรารี gosoap["github.com/tiaguinho/gosoap"] แล้ว

func main() {
    if soap, err := gosoap.SoapClient("https://domain:port/path?WSDL"); err != nil {
        fmt.Println(err)
        return
    } else {
        params := gosoap.Params{
            "param1": "abc",
            "param2":   "def",
            "param3":     "123",
        }

        if res, err := soap.Call("MethodName", params); err != nil {
            fmt.Println(err)
            return
        } else {
            fmt.Println(res)
            return
        }
    }
}

นี่คือข้อผิดพลาดที่ฉันได้รับ:

Get https://domain:port/path?WSDL: x509: certificate signed by unknown authority
  1. ฉันจะส่งส่วนหัวได้อย่างไร
  2. ฉันจะแก้ไขปัญหาใบรับรองได้อย่างไร

person Eric Fernandes    schedule 18.04.2019    source แหล่งที่มา
comment
ซึ่งหมายความว่า CA ที่ติดตั้งซึ่งแอปของคุณทำงานอยู่ไม่สามารถยืนยันใบรับรองได้   -  person Berkant Ipek    schedule 19.04.2019


คำตอบ (1)


ดังที่ความคิดเห็นของ Berkant กล่าวว่า "ซึ่งหมายความว่า CA ที่ติดตั้งซึ่งแอปของคุณทำงานอยู่ไม่สามารถยืนยันใบรับรองได้"

วิธีที่ดีที่สุดคือตรวจสอบว่าใบรับรองของโฮสต์ของคุณถูกต้องและกำหนดค่าอย่างเหมาะสมหรือไม่ หากโฮสต์ของคุณใช้ใบรับรองของคุณเอง วิธีที่ดีที่สุดคือเพิ่มใบรับรองดังกล่าวเพื่อให้ทราบใบรับรองของระบบ/สภาพแวดล้อมของคุณ คุณสามารถเพิ่มลงใน golang เองหรือเพิกเฉยก็ได้

หากต้องการเพิ่มใบรับรองของคุณเองลงใน golang ดูคำตอบนี้:

https://stackoverflow.com/questions/38822764/how-to-send-a-https-request-with-a-certificate-golang/38825553#38825553

จากนั้นตั้งค่าไคลเอนต์ดังนี้:

หากต้องการเพิกเฉย gosoap.Client จะมีฟิลด์ Client ที่อนุญาตให้ตั้งค่า http.Client แต่หลังจากเรียก gosoap.SoapClient เท่านั้น ดังนั้นคุณต้องเลียนแบบ gosoap.SoapClient:

func SoapClient(wsdl string) (*gosoap.Client, error) {
    _, err := url.Parse(wsdl)
    if err != nil {
        return nil, err
    }

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify : true},
    }

    //client := &http.Client{Transport: tr}//1: if you wanna add only soap headers
    client := &http.Client{Transport: NewAddHeaderTransport(tr)}//1: if you wanna add http headers

    //2: if you wann add soap headers, soap.Client has HeaderName and HeaderParams field

   soapClient := &gosoap.Client{
        HttpClient:      client,
        WSDL:        wsdl,
        URL:         strings.TrimSuffix(d.TargetNamespace, "/"),
    }

    err := getWsdlDefinitions(wsdl, &soapClient.Definitions, client)
    if err != nil {
        return nil, err
    }

    return soapClient, nil
}

//we use interface{} since gosoap.wsdlDefinitions is unexported
func getWsdlDefinitions(u string, wsdl interface{}, client *http.Client) (err error) {
    r, err := client.Get(u)
    if err != nil {
        return err
    }
    defer r.Body.Close()

    decoder := xml.NewDecoder(r.Body)
    decoder.CharsetReader = charset.NewReaderLabel
    return decoder.Decode(wsdl)
}

type AddHeaderTransport struct {
    T http.RoundTripper
}

func (adt *AddHeaderTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    req.Header.Add("Your-Header", "your header value")
    return adt.T.RoundTrip(req)
}

func NewAddHeaderTransport(T http.RoundTripper) *AddHeaderTransport {
    if T == nil {
        T = http.DefaultTransport
    }
    return &AddHeaderTransport{T}
}
person gstvg    schedule 07.05.2020