OneDrive API Python request.post untuk mengunggah file menghasilkan kesalahan 401

Saya mencoba menggunakan OneDrive API, ADAL dan Python request.post untuk mengunggah file ke folder Sharepoint tetapi saya mendapatkan kesalahan 401.

Otorisasi ADAL berfungsi untuk mendapatkan respons token yang benar dan menghasilkan access_token yang layak.

Saya dapat menggunakan access_token untuk mengunduh file dari folder Sharepoint yang sama.

Meskipun ini hanya berfungsi ketika saya secara manual menyalin print file_url url yang dibuat oleh kode ke browser. Namun urllib.urlretrieve(file_url, local_file_name) hanya membuat file bernama myfilename.csv dengan konten 403 Forbidden.

Otorisasi saya menggunakan nama pengguna dan kata sandi yang dikodekan, dan saya menyimpan token penyegaran dalam teks yang jelas, dan selalu mengambilnya ketika mengambil respons token:

import adal
import urllib
import requests

## set variables
username = '[email protected]'
password = 'mypassword'
authorization_url = 'https://login.windows.net/mydomain.onmicrosoft.com' # Authority
redirect_uri = 'https://login.microsoftonline.com/login.srf'
client_id = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' # Client id

## use ADAL to create token response
token_response = adal.acquire_token_with_username_password(
        authorization_url,
        username,
        password
    )

## create refresh token and save it to use later 
refresh_token = token_response['refreshToken']
refresh_token_file = open('refresh_token.txt', 'w')
refresh_token_file.write(refresh_token)
refresh_token_file.close()

## get saved refresh token and use it to get new token response
refresh_token = open('refresh_token.txt', 'r').read()
token_response = adal.acquire_token_with_refresh_token(authorization_url, str(refresh_token))

## get access_token from token response
access_token = token_response.get('accessToken') 

Respons token sudah benar dan menggunakan token akses darinya, kode berikut menghasilkan url file_url yang dapat saya salin dan tempel secara manual ke browser yang berhasil mengunduh file. Namun urllib.urlretrieve(file_url, local_file_name) hanya membuat file bernama myfilename.csv dengan konten 403 Forbidden:

## download file
file_url = 'https://mydomain.sharepoint.com/Shared%20Documents/myfoldername/myfilename.csv?token_response=' + str(access_token)
local_file_name = 'myfilename.csv'
urllib.urlretrieve(file_url, local_file_name)

Namun saya belum berhasil mengunggah ke folder Sharepoint ini. Saat ini saya memiliki yang berikut ini:

# upload file
site_url = 'https://mydomain.sharepoint.com/'
headers = {'Authorization':'BEARER ' + str(access_token)}
r = requests.post(site_url, files={'Shared%20Documents/myfoldername/myfilename.csv': open('myfilename.csv', 'rb')}, headers=headers)

print r.text

yang menghasilkan respons

401 UNAUTHORIZED 

Aplikasi Azure Active Directory saya memiliki izin:

Read and write all user files 
Read and write items and lists in all site collections
(not sure both are needed to upload files)

Apakah request.post saya terlihat baik-baik saja? Cukup yakin saya mengirimkan header, folder dan file dengan benar.

EDIT UNTUK MENAMBAHKAN:

Mengingat fakta bahwa kode unduhan mengembalikan 403 Forbidden dan kode unggahan mengembalikan 401 Unauthorized Saya curiga masalahnya ada pada cara urllib dan requests mengirim url.

EDIT UNTUK MENAMBAHKAN:

Mencoba membuat url file untuk digunakan di GET dan PUT. Setelah saya diautentikasi, saya dapat memasukkan url ini secara manual ke browser:

https://mydomain.sharepoint.com/_api/v1.0/files/root

yang mengembalikan XML berikut:

{"@odata.context":"https://mydomain.sharepoint.com/_api/v1.0/$metadata#files/$entity"
,"@odata.type":"#Microsoft.FileServices.Folder"
,"@odata.id":"https://mydomain.sharepoint.com/_api/v1.0/files/01QEW7725BZO3N6Y2GOV54373IPWSELRRZ"
,"@odata.editLink":"files/01QEW7725BZO3N6Y2GOV54373IPWSELRRZ"
,"createdBy":null
,"eTag":null
,"id":"01QEW7725BZO3N6Y2GOV54373IPWSELRRZ"
,"lastModifiedBy":null
,"name":"/"
,"parentReference":null
,"size":0
,"dateTimeCreated":"2013-07-31T02:35:57Z"
,"dateTimeLastModified":"2016-05-23T03:55:46Z"
,"type":"Folder"
,"webUrl":"https://mydomain.sharepoint.com/Shared%20Documents"
,"childCount":1}

Namun belum menemukan sintaks yang benar untuk referensi ke file tersebut. Misalnya ini tidak berfungsi:

https://mydomain.sharepoint.com/_api/v1.0/files/root:/myfoldername/myfilename.csv:/content

Ini mengembalikan kesalahan:

    {"error":"invalid_client","error_description":"Invalid audience Uri 'https:\/\/m
anagement.core.windows.net\/'."}

Saya pikir mendapatkan referensi khusus ke file ini adalah hal yang saya perlukan agar dapat berfungsi.


person curtisp    schedule 23.05.2016    source sumber
comment
Apakah Anda yakin Anda mengunduh file dengan benar? Saya mencoba kode Anda, alih-alih mengunduh file, itu memberi saya file html yang mengarahkan saya ke tempat lain.   -  person Jack Zeng    schedule 24.05.2016
comment
Sial, Anda benar, itu tidak diunduh dengan benar. Itu membuat file bernama myfilename.csv tetapi isinya hanya 403 Forbidden. Ketika saya mencetak file_url dan menyalin url yang dihasilkan ke browser secara langsung, file tersebut diunduh dengan benar. Saya akan memperbarui pertanyaan.   -  person curtisp    schedule 24.05.2016


Jawaban (1)


Ada beberapa hal yang perlu diperbaiki di sini.

Pertama, Anda harus meneruskan id klien dan sumber daya ke acquire_token_with_username_password Anda. Ini akan memungkinkan Anda mengakses Grafik (di mana Anda dapat mengakses OneDrive), jika tidak, Anda hanya mendapatkan izin masuk dalam token itu.

resource_url = "https://graph.microsoft.com";

token_response = ada.acquire_token_with_username_password(
    authorization_url,
    username,
    password,
    client_id
    resource_url
)

Jika Anda mendapatkan pesan kesalahan yang mengatakan bahwa client_secret atau client_assertion diperlukan. Anda perlu mendaftarkan Aplikasi Azure baru dan memilih Klien Asli. Jika Anda mendapatkan pesan kesalahan yang menyatakan bahwa Anda memerlukan perintah interaktif, Anda perlu menyetujui aplikasi secara manual untuk pertama kalinya di browser dengan menavigasi ke

https://login.microsoftonline.com/mydomain.com/oauth2/authorize?client_id=client_id&resource=resource_url&response_type=code+id_token&nonce=1234

Pastikan Anda Mengganti mydomain.com, client_id dan resource_url.

Anda hanya perlu melakukan ini sekali, pertama kali. Setelah masuk dengan browser dan menyetujui, Anda seharusnya tidak lagi mendapatkan kesalahan prompt interaktif tersebut.

Untuk mengunduh file, tidak yakin dari mana Anda mendapatkan pendekatan "?token_response=x" itu tetapi menurut saya itu tidak berhasil (tidak berhasil saat saya mengujinya). Anda memerlukan url yang berbeda dan mengirim token pembawa seperti yang Anda lakukan pada permintaan posting Anda.

site_url = 'https://graph.microsoft.com/v1.0/drive/root:/myfoldername/myfilename.csv:/content'
headers = {'Authorization':'BEARER ' + str(access_token)}
r = requests.get(site_url, headers=headers)
print r.text

Info selengkapnya tentang cara mendapatkan file di sini: https://dev.onedrive.com/items/download.htm

Sedangkan untuk mengunggah, Anda juga perlu mengubah URL Anda, ke nilai yang sama dengan kasus GET dan juga mengubah dari POST ke PUT.

site_url = 'https://graph.microsoft.com/v1.0/drive/root:/myfoldername/myfilename.csv:/content'
headers = {'Authorization':'BEARER ' + str(access_token)}
r = requests.put(site_url, data = open('myfilename.csv', 'rb')}, headers=headers)
print r.text

Info selengkapnya tentang mengunggah file di sini: https://dev.onedrive.com/items/upload_put.htm

person Saca    schedule 25.05.2016
comment
Oke, saya mengerti sekarang, saya baru saja mengautentikasi pengguna dengan Azure AD, bukan aplikasi. Namun adal.acquire_token_with_username_password menyetel keduanya client_id dan resource hingga None. - person curtisp; 26.05.2016
comment
Saya dapat mengotorisasi login.microsoftonline.com . Diperlukan modifikasi ADAL class _DefaultValues di file __init__.py yang memiliki nilai default untuk client_id dan resource sehingga cocok dengan nilai untuk aplikasi saya, misalnya client_id = client_id aplikasi Azure AD saya dan resource = https://tenant.sharepoint.com/untuk memperbaiki masalah audiens yang tidak valid. Juga memodifikasi file_url menjadi 'tenant.sharepoint .com/_api/v2.0/drive/root:/namafoldersaya/'. - person curtisp; 26.05.2016