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":"<>"}}
错误原因分析
- 受众不匹配:获取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中通过验证。 - 脚本逻辑冲突:脚本重复定义
ONEDRIVE_API_URL变量,最后生效的是SharePoint API地址,进一步放大了受众不匹配的问题。 - 遍历逻辑错误:
for FILE in "$SOURCE_FOLDER"仅会遍历文件夹本身,不会处理其中的文件,导致上传逻辑无法正常执行。
解决方法
方案一:使用Microsoft Graph API上传到共享OneDrive文件夹
- 修正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" - 配置Azure AD权限:在Azure门户为应用添加Microsoft Graph的应用权限
Files.ReadWrite.All,并完成管理员同意。 - 修复文件遍历:调整循环逻辑遍历文件夹内的文件,跳过非文件项:
for FILE in "$SOURCE_FOLDER"/*; do [ -f "$FILE" ] || continue # 后续上传逻辑 done
方案二:改用SharePoint API上传(保留原API地址)
- 调整token请求scope:将scope替换为SharePoint站点的资源标识符:
-d "scope=https://$TENANT_ID.sharepoint.com/.default" - 配置Azure AD权限:在Azure门户为应用添加SharePoint的应用权限
Sites.ReadWrite.All,并完成管理员同意。 - 修复文件遍历:同方案一的第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
相关产品推荐
相关产品推荐

