You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins集成OneDrive API遇认证失败:InvalidAuthenticationToken问题求助

问题:Jenkins集成OneDrive API认证失败(Invalid audience)

我正尝试将现有Jenkins任务与OneDrive API集成,实现从Jenkins向共享OneDrive文件夹上传文件,但在OneDrive认证环节出现问题。以下是我的bash脚本:

#!/bin/bash
# Define your variables
CLIENT_ID="<>"
CLIENT_SECRET="<>"
TENANT_ID="<>"
# Define the folder where your Jenkins instance stores the files
SOURCE_FOLDER="/Users/<>/Desktop/TEST"

# Define the folder path in OneDrive where you want to upload the files
ONEDRIVE_FOLDER_PATH=""

# Authenticate and obtain an access token
TOKEN_RESPONSE=$(curl -X POST "https://login.microsoftonline.com/$TENANT_ID/oauth2/token" \
     -d "client_id=$CLIENT_ID" \
     -d "client_secret=$CLIENT_SECRET" \
     -d "grant_type=client_credentials" \
     -d "scope=https://graph.microsoft.com/.default")

# Extract the access token from the JSON response
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')

if [ -z "$ACCESS_TOKEN" ]; then
    echo "Failed to obtain an access token."
    exit 1
fi

# Loop through files in the source folder and upload them to OneDrive
for FILE in "$SOURCE_FOLDER"; do
    FILE_NAME=$(basename "$FILE")
    ONEDRIVE_API_URL="https://graph.microsoft.com/v1.0/me/drive/root:$ONEDRIVE_FOLDER_PATH/$FILE_NAME:/content"
    ONEDRIVE_API_URL="https://$TENANT_ID.sharepoint.com/CRM/_api/v2.0/drive/root:$ONEDRIVE_FOLDER_PATH/$FILE_NAME:/content"

    # Calculate the content length of the file
    CONTENT_LENGTH=$(wc -c < "$FILE")

    # Use curl to upload the file to OneDrive with the "Content-Length" header
    UPLOAD_RESPONSE=$(curl -X PUT -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Length: $CONTENT_LENGTH" --upload-file "$FILE" "$ONEDRIVE_API_URL")

    if [ $? -eq 0 ]; then
        echo "File '$FILE_NAME' uploaded to OneDrive successfully."
    else
        echo "Failed to upload file '$FILE_NAME' to OneDrive."
    fi
done

# Exit with success
exit 0

收到的错误信息如下:

{"code":"InvalidAuthenticationToken","message":"Access token validation failure. Invalid audience.","innerError":{"date":"2023-09-28T14:25:58","request-id":"<>","client-request-id":"<>"}}


错误原因分析

  1. 受众不匹配:获取token时使用的是Microsoft Graph API的scope(https://graph.microsoft.com/.default),但实际调用的是SharePoint站点的API地址(https://$TENANT_ID.sharepoint.com/CRM/_api/v2.0/...)。每个API有专属的受众标识,为Graph生成的token无法在SharePoint API中通过验证。
  2. 脚本逻辑冲突:脚本重复定义ONEDRIVE_API_URL变量,最后生效的是SharePoint API地址,进一步放大了受众不匹配的问题。
  3. 遍历逻辑错误:for FILE in "$SOURCE_FOLDER"仅会遍历文件夹本身,不会处理其中的文件,导致上传逻辑无法正常执行。

解决方法

方案一:使用Microsoft Graph API上传到共享OneDrive文件夹

  1. 修正API地址:删除SharePoint API的定义,改用Graph API针对站点共享文件夹的格式(client_credentials模式无当前用户上下文,不能用/me/drive):
    SITE_NAME="CRM" # 你的SharePoint站点名称
    ONEDRIVE_API_URL="https://graph.microsoft.com/v1.0/sites/$TENANT_ID.sharepoint.com:$SITE_NAME/drive/root:$ONEDRIVE_FOLDER_PATH/$FILE_NAME:/content"
    
  2. 配置Azure AD权限:在Azure门户为应用添加Microsoft Graph的应用权限Files.ReadWrite.All,并完成管理员同意。
  3. 修复文件遍历:调整循环逻辑遍历文件夹内的文件,跳过非文件项:
    for FILE in "$SOURCE_FOLDER"/*; do
        [ -f "$FILE" ] || continue
        # 后续上传逻辑
    done
    

方案二:改用SharePoint API上传(保留原API地址)

  1. 调整token请求scope:将scope替换为SharePoint站点的资源标识符:
    -d "scope=https://$TENANT_ID.sharepoint.com/.default"
    
  2. 配置Azure AD权限:在Azure门户为应用添加SharePoint的应用权限Sites.ReadWrite.All,并完成管理员同意。
  3. 修复文件遍历:同方案一的第3步。

修正后的脚本示例(方案一)

#!/bin/bash
# Define your variables
CLIENT_ID="<>"
CLIENT_SECRET="<>"
TENANT_ID="<>"
SITE_NAME="CRM" # 你的SharePoint站点名称
SOURCE_FOLDER="/Users/<>/Desktop/TEST"
ONEDRIVE_FOLDER_PATH="" # 共享文件夹在站点中的路径,比如"/Shared Documents/Test"

# Authenticate and obtain an access token
TOKEN_RESPONSE=$(curl -X POST "https://login.microsoftonline.com/$TENANT_ID/oauth2/token" \
     -d "client_id=$CLIENT_ID" \
     -d "client_secret=$CLIENT_SECRET" \
     -d "grant_type=client_credentials" \
     -d "scope=https://graph.microsoft.com/.default")

ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')

if [ -z "$ACCESS_TOKEN" ]; then
    echo "Failed to obtain an access token."
    exit 1
fi

# Loop through files in the source folder
for FILE in "$SOURCE_FOLDER"/*; do
    [ -f "$FILE" ] || continue
    FILE_NAME=$(basename "$FILE")
    ONEDRIVE_API_URL="https://graph.microsoft.com/v1.0/sites/$TENANT_ID.sharepoint.com:$SITE_NAME/drive/root:$ONEDRIVE_FOLDER_PATH/$FILE_NAME:/content"

    UPLOAD_RESPONSE=$(curl -X PUT -H "Authorization: Bearer $ACCESS_TOKEN" --upload-file "$FILE" "$ONEDRIVE_API_URL")

    if [ $? -eq 0 ]; then
        echo "File '$FILE_NAME' uploaded to OneDrive successfully."
    else
        echo "Failed to upload file '$FILE_NAME' to OneDrive. Response: $UPLOAD_RESPONSE"
    fi
done

exit 0

内容的提问来源于stack exchange,提问作者jsalerno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:44:58