使用Golang的Azure SDK通过证书访问经典API

使用Golang的Azure SDK通过证书访问经典API 你好,

我是Go语言的新手,第一个任务是用它来查询旧版Azure"经典"API(即Azure服务管理API)的信息。

微软提供了一个用于在Go中使用Azure的SDK:

Azure for Go developers - Tutorials, API Reference

Azure for Go developers - Tutorials, API Reference

使用以下开发者资源开始使用Azure SDK for Go进行开发。

我已经成功使用它调用了ARM Azure API(新/当前模型),但我还需要访问旧的经典API。我看到SDK在这里支持这一点:

Package sdk

Package sdk

Package sdk 提供了用于管理和使用Azure服务的Go包。

^ 这里显示了一些专门用于"经典"的包。我遇到的问题是关于ARM的,我提供的基本上是一个API ID和密钥,这方面有示例,因为这是最常见的用法。然而,对于这些经典包,我必须使用证书。我有在Windows上创建的证书(一个包含公钥并已上传到Azure的.cer文件,以及一个包含私钥并位于我本地机器上的.pfx文件)。我找不到任何关于如何实际使用此证书向Azure进行身份验证的示例。

根据之前的链接,我推测应该从这个包开始:

Package management

Package management

Package management 提供了主要的API客户端,用于构造其他客户端并向Microsoft Azure服务管理REST API发出请求。

其中有一个函数签名如下:

func NewClient(subscriptionID string, managementCert []byte) (Client, error)

^ https://godoc.org/github.com/Azure/azure-sdk-for-go/services/classic/management#NewClient

我不知道如何从我目前的状态(拥有一个pfx文件)到正确调用此函数?我看到它需要将证书作为字节切片,但我不知道pfx是否已经是正确的格式,以及/或者如何将其转换为字节切片?

任何帮助/指导都将非常感激。

此致, -djc


更多关于使用Golang的Azure SDK通过证书访问经典API的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

对于其他可能遇到这个问题的人:

  1. 我使用 openssl 将 pfx 文件转换为包含公钥和私钥的 pem 文件。在我的情况下,我使用了 Windows 的 Linux 子系统(Ubuntu on Bash)以便更方便地访问 openssl 工具。从 Linux 子系统访问已在我 Windows 文件系统上的 pfx 文件是安全/没问题的,但反过来不行。换句话说,使用 Linux 子系统中的 openssl 来转换 Windows 文件系统上的文件是可以的,Linux 工具可以通过 /mnt/c 挂载点(或 /mnt/d、/mnt/e 等)无问题地写入 Windows 文件系统。但是你不能使用 Windows 工具来编辑 Linux 文件系统上的文件。

  2. 然后,使用类似下面的代码开始,这个初始客户端将作为创建其他特定服务客户端的输入: 你的导入需要包含 classic/management 行,如下所示: import “github.com/Azure/azure-sdk-for-go/services/classic/management

 subID := "your azure subscription id"
 
 certBytes, err := ioutil.ReadFile("/util/ForAzureClassic.pem")

 if err != nil {
     log.Fatal(err)
 }
 
 classicClient, err := management.NewClient(subID, certBytes)
 if err != nil {
     log.Fatal(err)
 }

现在,classicClient 变量在创建特定服务客户端时会被使用,比如用于虚拟网络、虚拟机等等。

更多关于使用Golang的Azure SDK通过证书访问经典API的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


要使用Golang的Azure SDK通过证书访问经典API,你需要从PFX文件中提取证书和私钥,并将其转换为所需的字节格式。以下是具体实现方法:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "io/ioutil"
    "log"

    "github.com/Azure/azure-sdk-for-go/services/classic/management"
)

// 从PFX文件加载证书
func loadCertificateFromPfx(pfxPath, password string) ([]byte, error) {
    // 读取PFX文件
    pfxData, err := ioutil.ReadFile(pfxPath)
    if err != nil {
        return nil, fmt.Errorf("读取PFX文件失败: %v", err)
    }

    // 解析PFX数据
    privateKey, certificate, err := pkcs12.Decode(pfxData, password)
    if err != nil {
        return nil, fmt.Errorf("解析PFX数据失败: %v", err)
    }

    // 将证书编码为PEM格式
    certPEM := pem.EncodeToMemory(&pem.Block{
        Type:  "CERTIFICATE",
        Bytes: certificate.Raw,
    })

    // 将私钥编码为PEM格式
    keyPEM, err := x509.MarshalPKCS8PrivateKey(privateKey)
    if err != nil {
        return nil, fmt.Errorf("编码私钥失败: %v", err)
    }

    keyPEMBlock := pem.EncodeToMemory(&pem.Block{
        Type:  "PRIVATE KEY",
        Bytes: keyPEM,
    })

    // 合并证书和私钥(Azure经典API需要这种格式)
    managementCert := append(certPEM, keyPEMBlock...)
    return managementCert, nil
}

// 使用golang.org/x/crypto/pkcs12的替代实现
func decodePfx(pfxData []byte, password string) (interface{}, *x509.Certificate, error) {
    // 注意:实际使用时需要导入 "golang.org/x/crypto/pkcs12"
    // 这里简化处理,实际需要调用pkcs12.Decode
    return pkcs12.Decode(pfxData, password)
}

func main() {
    subscriptionID := "你的订阅ID"
    pfxPath := "path/to/your/certificate.pfx"
    pfxPassword := "你的PFX密码"

    // 加载证书
    managementCert, err := loadCertificateFromPfx(pfxPath, pfxPassword)
    if err != nil {
        log.Fatalf("加载证书失败: %v", err)
    }

    // 创建经典API客户端
    client, err := management.NewClient(subscriptionID, managementCert)
    if err != nil {
        log.Fatalf("创建客户端失败: %v", err)
    }

    fmt.Println("成功创建Azure经典API客户端")

    // 示例:获取云服务列表
    cloudServicesClient := client.GetCloudServicesClient()
    services, err := cloudServicesClient.List()
    if err != nil {
        log.Fatalf("获取云服务列表失败: %v", err)
    }

    fmt.Printf("找到 %d 个云服务\n", len(services))
}

你还需要安装PKCS#12支持包:

go get golang.org/x/crypto/pkcs12

以下是更完整的实现,包含错误处理和TLS配置:

import (
    "crypto/tls"
    "crypto/x509"
    "encoding/pem"
    "io/ioutil"
    
    "golang.org/x/crypto/pkcs12"
)

func createClassicClient(subscriptionID, pfxPath, password string) (*management.Client, error) {
    // 读取PFX文件
    pfxData, err := ioutil.ReadFile(pfxPath)
    if err != nil {
        return nil, err
    }

    // 使用pkcs12包解码
    privateKey, cert, err := pkcs12.Decode(pfxData, password)
    if err != nil {
        return nil, err
    }

    // 创建TLS证书
    tlsCert := tls.Certificate{
        Certificate: [][]byte{cert.Raw},
        PrivateKey:  privateKey,
    }

    // 将TLS证书转换为字节切片
    certPEM := pem.EncodeToMemory(&pem.Block{
        Type:  "CERTIFICATE", 
        Bytes: cert.Raw,
    })

    keyBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
    if err != nil {
        return nil, err
    }

    keyPEM := pem.EncodeToMemory(&pem.Block{
        Type:  "PRIVATE KEY",
        Bytes: keyBytes,
    })

    managementCert := append(certPEM, keyPEM...)
    
    return management.NewClient(subscriptionID, managementCert)
}

这样你就可以使用PFX证书成功创建Azure经典API客户端并进行API调用了。

回到顶部