func authenticateWithHeaderMap()

in example/http_authorization.go [53:150]


func authenticateWithHeaderMap(method, path string, headers map[string]string) bool {
	// Get string to sign
	var serviceHeaders []string
	for k, v := range headers {
		if strings.HasPrefix(strings.ToLower(k), "x-mns-") {
			serviceHeaders = append(serviceHeaders, fmt.Sprintf("%s:%s", k, v))
		}
	}

	sort.Strings(serviceHeaders)
	serviceStr := strings.Join(serviceHeaders, "\n")
	var signHeaderList []string
	for _, key := range []string{"content-md5", "content-type", "date"} {
		if val, ok := headers[key]; ok {
			signHeaderList = append(signHeaderList, val)
		} else {
			signHeaderList = append(signHeaderList, "")
		}
	}

	str2sign := fmt.Sprintf("%s\n%s\n%s\n%s", method, strings.Join(signHeaderList, "\n"), serviceStr, path)
	fmt.Println("String to sign:", str2sign)

	// 获取证书的URL
	certURLBase64, ok := headers["x-mns-signing-cert-url"]
	if !ok {
		fmt.Println("x-mns-signing-cert-url Header not found")
		return false
	}

	certURLBytes, err := base64.StdEncoding.DecodeString(certURLBase64)
	if err != nil {
		fmt.Println("Failed to decode base64 cert URL:", err)
		return false
	}

	certURL := string(certURLBytes)
	fmt.Println("x-mns-signing-cert-url:\t", certURL)

	// 根据URL获取证书,并从证书中获取公钥
	resp, err := http.Get(certURL)
	if err != nil {
		fmt.Println("Failed to fetch certificate:", err)
		return false
	}
	//goland:noinspection GoUnhandledErrorResult
	defer resp.Body.Close()

	//goland:noinspection GoDeprecation
	certData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Failed to read certificate:", err)
		return false
	}

	block, _ := pem.Decode(certData)
	if block == nil || block.Type != "CERTIFICATE" {
		fmt.Println("Failed to decode PEM block containing the certificate")
		return false
	}

	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		fmt.Println("Failed to parse certificate:", err)
		return false
	}

	pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
	if !ok {
		fmt.Println("Failed to cast public key to RSA public key")
		return false
	}

	// 对Authorization字段做Base64解码
	signatureBase64, ok := headers["authorization"]
	if !ok {
		fmt.Println("Authorization Header not found")
		return false
	}

	signature, err := base64.StdEncoding.DecodeString(signatureBase64)
	if err != nil {
		fmt.Println("Failed to decode base64 signature:", err)
		return false
	}

	// 认证
	hash := sha1.New()
	hash.Write([]byte(str2sign))
	digest := hash.Sum(nil)
	err = rsa.VerifyPKCS1v15(pubKey, crypto.SHA1, digest, signature)
	if err != nil {
		fmt.Println("Signature verification failed:", err)
		return false
	}

	return true
}