2016-05-23 21 views
0

OneDrive API、ADAL、Python request.postを使用してSharepointフォルダにファイルをアップロードしようとしていますが、401エラーが発生しています。OneDrive APIファイルをアップロードするためのPython request.postで401エラーが発生する

正確なトークンレスポンスを取得し、実行可能なaccess_tokenが生成されるため、ADAL認証が機能しています。

access_tokenを使用して、同じSharepointフォルダからファイルをダウンロードできます。

これは、手動でコードによって作成されたprint file_urlのURLをブラウザにコピーする場合にのみ機能しますが、しかし、urllib.urlretrieve(file_url, local_file_name)は、内容が403 Forbiddenmyfilename.csvという名前のファイルのみを作成します。

私の許可は、ハードコーディングされたユーザー名とパスワードを使用し、私はクリアテキストでリフレッシュトークンを保存し、トークンの応答を取得する際に、常にそれを取得しています:

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') 

トークン応答が正しいとからアクセストークンを使用しています次のコードは、ファイルを正常にダウンロードするブラウザに手動でコピー&ペーストすることができるfile_url URLを生成します。私はまだ正常にこのSharepointのフォルダにアップロードすることができませんでしたが

## 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) 

:しかしurllib.urlretrieve(file_url, local_file_name)は内容だけ403 Forbiddenmyfilename.csvという名前のファイルを作成します。現在、私は次のようしている:

# 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 

応答を生成

401 UNAUTHORIZED 

マイアズールADアプリは権限があります。

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

を私request.postは大丈夫見ていますか?私はヘッダー、フォルダ、ファイルを正しく送信していることを確かめてください。

EDIT追加する:

を考えると、実際に両方のダウンロードコードが403 Forbiddenを返し、アップロードのコードは、私は問題がどのようurllibrequests URLを送信しているとの疑いがある401 Unauthorizedを返すこと。追加する

EDIT:

がGETやPUTで使用するファイルのURLを構築しようとしています。私が認証していた後、私は手動でブラウザにこのURLを入力することができます。

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

XMLを次返す:

{"@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} 

ただし、ファイルへの参照のための正しい構文を発見していません。たとえばこれが動作していません。

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

これはエラーを返して:

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

私は、ファイルには、この特定の参照を取得すると、私はそれを動作させるためにするために必要なものだと思います。

+1

は、あなたがあなたのファイルを正しくダウンロードしましたか?あなたのコードを試しましたが、ファイルをダウンロードする代わりに、私に別の場所にリダイレクトするhtmlファイルがあります。 –

+0

あなたは正しくそれが正しくダウンロードされていません。 'myfilename.csv'という名前のファイルを作成しますが、内容は' 403禁止されています。 'file_url'を出力し、結果のURLをブラウザに直接コピーすると、ファイルが正しくダウンロードされます。私は質問を更新します。 – curtisp

答えて

1

ここにはいくつか修正する必要があります。

まず、クライアントIDとリソースをacquire_token_with_username_passwordに渡す必要があります。これにより、(OneDriveにアクセスできる)グラフにアクセスすることができます。それ以外の場合は、そのトークンでサインインパーミッションを取得するだけです。

エラーが発生した場合は、client_secret o client_assertionが必要です。新しいAzure Appを登録してNative Clientを選択する必要があります。 あなたは、あなたが交換することを確認し、手動で必要

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

に移動して、ブラウザでの初めてのアプリに同意するだろう対話プロンプトを必要とするというエラーが出た場合mydomain.com、CLIENT_IDおよびresource_url。

これは最初に1回だけ行う必要があります。ブラウザでサインインして同意すると、その対話型のプロンプトエラーは表示されなくなります。

ファイルをダウンロードするには、 "token_response = x"というアプローチが得られた場所がわからないのですが、うまくいかないと思います(テストしたときにうまくいかなかった)。ポストリクエストでやっているように、別のURLが必要で、ベアラトークンを送信する必要があります。 、あなたがGETの場合と同じ値に、同様にあなたのURLを変更してもPOSTから変更する必要がありますアップロード用として https://dev.onedrive.com/items/download.htm

:ここでは、ファイルを取得上の

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 

詳細情報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 

詳細情報: https://dev.onedrive.com/items/upload_put.htm

+0

さて、私はちょうど今、私はちょうどアプリではないAzure ADのユーザーを認証している。しかし、['adal.acquire_token_with_username_password'](https://github.com/AzureAD/azure-activedirectory-library-for-python/blob/master/adal/__init__.py)は' client_id'と 'resource'を'なし。 – curtisp

+0

私は 'login.microsoftonline.com'を承認することができました。 __init __。py'ファイル([https://github.com/AzureAD/azure-activedirectory-library-for-python/blob/master/adal/__init__.py)で[ADALの 'class _DefaultValues'を修正する必要があります。 'client_id'と' resource'のデフォルト値が私のアプリケーションの値と一致するようにします。たとえば、 'client_id' = my AzureのADアプリのclient_idと' resource' = 'https://tenant.sharepoint.com/'が無効なオーディエンスの問題を修正します。また、file_urlを 'https://tenant.sharepoint.com/_api/v2.0/drive/root:/myfoldername/myfilename.csv:/content'に変更しました。 – curtisp

関連する問題