使用客户端证书和Golang获取访问令牌Azure AD

时间:2020-08-28 07:38:44

标签: azure go azure-active-directory azure-ad-graph-api

我正在尝试使用客户端证书从azure广告中进行现代身份验证。 该过程说。

  1. 创建一个Azure应用程序。
  2. 将证书上传到Azure应用程序并获取指纹。
  3. 使用该证书(https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials)生成JWT令牌
  4. 然后使用该jwt-token获取访问令牌。
  5. 要获取访问令牌,请调用API(https://login.microsoftonline.com/ / oauth2 / token)
  6. HTTP方法的类型为 POST ,并且帖子正文数据将为 x-www-form-urlencoded

完成所有步骤后,我尝试获取令牌。 我收到此错误。

{
    "error": "invalid_client",
    "error_description": "AADSTS700023: Client assertion audience claim does not match Realm issuer. Review the documentation at https://docs.microsoft.com/azure/active-directory/develop/active-directory-certificate-credentials .\r\nTrace ID: 714b5009-b74d-46b5-bd0e-3bea76272a01\r\nCorrelation ID: 2cb703bb-f325-44b5-a669-605bc7a81ac0\r\nTimestamp: 2020-08-28 07:31:19Z",
    "error_codes": [
        700023
    ],
    "timestamp": "2020-08-28 07:31:19Z",
    "trace_id": "714b5009-b74d-46b5-bd0e-3bea76272a01",
    "correlation_id": "2cb703bb-f325-44b5-a669-605bc7a81ac0"
}

我正在使用go代码生成JWT令牌并解析PFX文件。

func getAuthJWTToken() (string, error) {
    clientID := "**********************"
    _tenantName := "******************"
    pfxFilePath := `E:\abcd.pfx`
    certPassword := `*********`
    authToken := ""
    pfxFile, err := os.Open(pfxFilePath)

    if err != nil {
        return authToken, err
    }

    pfxfileinfo, _ := pfxFile.Stat()

    var size int64 = pfxfileinfo.Size()

    pfxbytes := make([]byte, size)
    buffer := bufio.NewReader(pfxFile)
    _, err = buffer.Read(pfxbytes)

    //PFX to PEM for computation of signature
    var pembytes []byte
    blocks, err := pkcs12.ToPEM(pfxbytes, certPassword)

    for _, b := range blocks {
        pembytes = append(pembytes, pem.EncodeToMemory(b)...)
    }

    //Decoding the certificate contents from pfxbytes
    pk, cert, err := pkcs12.Decode(pfxbytes, certPassword)
    if cert == nil {
        fmt.Printf("Bye")
        return authToken, nil
    }
    if pk == nil {

    }

    pfxFile.Close() // close file

    notToBeUsedBefore := time.Now()
    expirationTime := time.Now().Add(3000 * time.Minute)
    URL := fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/token", _tenantName)

    id := guid.New()

    claims := &claims{
        StandardClaims: jwt.StandardClaims{
            // In JWT, the expiry time is expressed as unix milliseconds
            ExpiresAt: expirationTime.Unix(),
            Audience:  URL,
            Issuer:    clientID, // consumer key of the connected app, hardcoded
            NotBefore: notToBeUsedBefore.Unix(),
            Subject:   clientID,
            Id:        id.String(),
        },
    }

    //token_header    map[string]interface{}

    token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)

    sha1Fingerprint := sha1.Sum(cert.Raw)
    var slice []byte
    slice = sha1Fingerprint[:]
    b64FingerPrint := base64.StdEncoding.EncodeToString([]byte(slice))
    token.Header["x5t"] = b64FingerPrint

    signKey, err := jwt.ParseRSAPrivateKeyFromPEM(pembytes) // parse the RSA key

    tokenString, err := token.SignedString(signKey) // sign the claims with private key

    fmt.Printf(fmt.Sprintf("JWT token is %s", tokenString))

    return tokenString, err
}

我需要帮助来解决此问题。

0 个答案:

没有答案