Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OneDrive for Business App Only token error with download #280

Closed
Deblanko opened this issue Dec 23, 2015 · 30 comments
Closed

OneDrive for Business App Only token error with download #280

Deblanko opened this issue Dec 23, 2015 · 30 comments

Comments

@Deblanko
Copy link

I have successfully configured an App Only token, for use on a test site, and used it to list, create folders, move items, delete items and upload files. However when trying to download a file I do not get the documented 302 status but instead I get a 404 not found, followed by a html body that informs me "Sorry, you cannot access this document. Please contact the person who shared it with you."

If I use the @content.downloadUrl from the meta data I get the same response.
Going into Sharepoint and providing everyone read access allows me to download the file.

In Azure I have given the app, associated with the App Only token, all the access available.

I am confused since I can do writeable actions but not read the contents of files.

I have tried both url approaches and many other permutations of configuration on Azure AD, all to no avail:
https://{tenant}-my.sharepoint.com/personal/{user}/_api/v2.0/drive/items/01CGGKSYALIMOHMA23JBFKIGR4EJJS7NRG/content
and
https://{tenant}-my.sharepoint.com/personal/{user}/_api/v2.0/drive/root:/test.txt:/content

Thanks in advance
Paul

Confirmation of consent granted.
screen shot 2015-12-17 at 08 00 18

PS. All folder/files I create are marked as being created by SharePoint App, I would have expected either the owner or then name of the App to be used instead.

@ificator
Copy link
Contributor

We can repro this issue and are investigating a fix now.

@ificator
Copy link
Contributor

ificator commented Jan 7, 2016

We've determine what the issue is and are trying to decide on a solution. No ETA yet I'm afraid.

@rgregg
Copy link
Contributor

rgregg commented Feb 4, 2016

There is a workaround available. You can fall back to the SharePoint REST API for downloading files in this scenario (when using app tokens). There's an app token sample I've been working on that isn't completely ready for prime-time yet, but you can see the DownloadFile method, which translates from OneDrive API to SharePoint REST to be able to download a file.

@Schweigi
Copy link

I can confirm the bug is still open but the suggested workaround is working well.

Btw. @rgregg the sample app fails when trying to list the user files (redirects back to the home site).

@Deblanko
Copy link
Author

I can also confirm that although the bug is still open the workaround is fine
Thanks for the help :-)

@max-mulawa
Copy link

Have you tried using DriveId as I was successful with accessing file content through the following API request with App-Only token.

https://{tenant}-my.sharepoint.com/_api/v2.0/drives/{DriveId}/items/{ItemId}/content

@Deblanko
Copy link
Author

I could not get DriveId to work since /Drives is not supported in OneDrive for Business?
However I did try ItemId, although that did not mp to our file model, but it failed anyway
The workaround works and I'm hoping for a fix soon :-)

@Deblanko Deblanko reopened this Mar 10, 2016
@max-mulawa
Copy link

App-only token with FullControl over the Office365 tenant gives access to /Drives/{DriveId} of all OneDrive for Business users within given tenant, also /Drives/{CurrentUserDriveId} works perfectly fine with user access token. I've checked both options.

@Deblanko
Copy link
Author

Did it only work with ItemId?
I tried all of these with no luck
// String url = oneDriveApi+userId+"/_api/v1.0/drive/root:"+encodedPath+":/content";
// String url = oneDriveApi+userId+"/_api/v2.0/drive/root:"+ encodedPath + "?select=@content.downloadUrl";
// String url = oneDriveApi+userId+"/_api/v2.0/drive/root:"+ encodedPath + ":/content";
// String url = oneDriveApi+userId+"/_api/v2.0/drive/items/01CGGKSYALIMOHMA23JBFKIGR4EJJS7NRG/content";

So if I wanted root: what is its DriveId?
Also does it work with an encodedPath since I have no storage in my model for the ItemId and can only use the path
Cheers
Paul

@max-mulawa
Copy link

This is the exact request I was submitting to get Item metadata from any drive:
https://{tenantid}-my.sharepoint.com/_api/v2.0/drives/{driveId}/items/{itemId}/

For root folder I run:
https://{tenantid}-my.sharepoint.com/_api/v2.0/drives/{driveId}/root/

I would expect this will work with path queries also, as the relative part to the root and access token attached are the most important.

I'm not sure if that helps, but this is me answering myself after few days on SO http://stackoverflow.com/questions/35819627/download-shared-file-programmatically-using-onedrive-for-business-api :)

@Deblanko
Copy link
Author

This link https://dev.onedrive.com/odb-preview/release-notes.htm#enumerating-drives says I cannot use /drives however that aside I wonder if it the itemID that makes the API call work?
Also your SO says you use client secret but i though that dd not work for AppOnly token, I tried that first, so I shifted to certificates.

Also looking at your call there is no UPN in the REST API so how are you using an AppOnly token to access all the different user's accounts with a single AppOnly token?

@max-mulawa
Copy link

I did not intend to enumerate drives, what I used /drives command to is accessing files on different drives within a tenant.

UPN is the driveId. App-only token has 'FullControl over Tenant' permissions and from my trial-error it appears that I can use this token to access any OneDrive for Business site through SharePoint or OdB APIs. Look at this article where Azure WebJob customizes users OneDrive for Business sites http://blogs.msdn.com/b/vesku/archive/2015/01/05/customizing-onedrive-for-business-sites-with-app-model.aspx using App-only token.

@Deblanko
Copy link
Author

When I tried to get the token using client secret it failed to work and this link, http://www.andrewconnell.com/blog/user-app-app-only-permissions-client-credentials-grant-flow-in-azure-ad-office-365-apis, among others, showed how to use it along with the need for the admin to grant access.
I'm not running anything in Azure/Sharepoint, only using Azure as the placeholder for my app details, and accessing OneDrive from our server service. However your approach looks interesting :-)
We have a prototype, in Java, with the workaround, working now, so I guess we will just be waiting for the AppOnly cert method fix for our production code.
Does the client secret method need any admin grant confirmation?

@max-mulawa
Copy link

The client secret is provided during SharePoint add-in registration. When this SharePoint add-in is actually installed on the SharePoint Online site collection in your tenant, this is when your app-only token gets the permission specified in SharePoint add-in manifest.

After installation you are free to use following code to retrieve valid Access Token, with TokenHelper being Visual Studio class generated by SharePoint Add-in project.

Uri url = new Uri("https://{tenant}-my.sharepoint.com/personal/{UPN}/"); string realm = TokenHelper.GetRealmFromTargetUrl(url); var token = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, url.Authority, realm).AccessToken;

and with ClientId and ClientSecret in the configuration file
<appSettings> <add key="ClientId" value="*" /> <add key="ClientSecret" value="*" /> </appSettings>

@Deblanko
Copy link
Author

We don't produce a Sharepoint Add-In. Instead we use a native server app to access One Drive for Business. Perhaps that is the confusion as to why your approach works and we we're having problems with the download?
The native app, app only token, approach only works with a certificate signing approach, and not a client secret, it is interesting though that you use the drive id and not the UPN, probably worth us investigating but as I said the workaround is working for us and a fix is promised :-)

@sbukhtiyarov
Copy link

sbukhtiyarov commented Oct 20, 2016

@rgregg, @ificator , do you have any news about this issue?
Using GetFileByServerRelativeUrl might be difficult in some cases, like as file names in Hebrew.
For example, how to make correct url for the "New Text Document.txt" in Hebrew?

סמך טקסט ‫חדש.txt

@dtheodor
Copy link

It's been a year now, any progress?

@dtheodor
Copy link

While the Sharepoint REST API workaround works, it is incomplete in that it does not support byte range requests

@HamletHakobyan
Copy link

Hi there,

is there any progress on this issue? The workarounds suggested in this and surrounding threads doesn't work for me.
Any reasonable suggestions?

Thanks.

@RichardPointon
Copy link

There are also issues with the workaround in that files that can be uploaded can't be downloaded either due to invalid characters or path length.

@ificator
Copy link
Contributor

ificator commented May 5, 2017

The download links for app-only should now be functional - is anyone still encountering issues? If so, it would be useful to know the number of characters in the query string of one of the URLs that is failing.

@RichardPointon
Copy link

No still failing with 404.

First part returns 302 and url as expected. When trying to access the returned location url returns 404 not found.

@dtheodor
Copy link

dtheodor commented May 30, 2017

I was able to download a file through an app-only token, including range requests

@wbreza
Copy link

wbreza commented Jun 21, 2017

Download still fails for me @ificator . Total length of url is 2457 which is over the 2048 typical limit. I imagine this is why it is failing.

@wbreza
Copy link

wbreza commented Jun 21, 2017

I did find a workaround where if you extract the "access_token" from the querystring and instead add an "Authorization" header for the HTTP request as "Bearer {accessToken}" the download will work.

@yuribb
Copy link

yuribb commented Jun 23, 2017

I've found a workaround to resolve the issue. If you authenticate by using service account - you should use your access token, not token in downloadUrl. Your download url should look like: "https://tenant.sharepoint.com/_layouts/15/download.aspx?UniqueId=12345678-90ab-cdef-0123-4567890abcde" and header "Authorization: Bearer accessToken".

@ificator ificator self-assigned this Jul 13, 2017
@ificator
Copy link
Contributor

We've been working to reduce the size of URLs with attached tokens and latest changes should now be fully deployed. Hopefully download URLs will now no longer arbitrarily fail due to URL length, but please let us know if any of you continue to see such issues.

@JWiersema
Copy link

JWiersema commented Oct 20, 2017

@ificator : Hopefully I understand this issue and the status correctly, so I'm in the right place.
I'm facing the error 404 filenotFound when accessing a graph resource with App-only tokens. The URL works in the graphExplorer. Since I'm getting a 404 and not an access denied I assume my app has the required rights to get the file (not 100% sure). The URL is very long (getting a chart from an excel file in SP). URL is 343 characters long.

https://graph.microsoft.com/v1.0/sites/tenant,site-id,web-id/drives/long-id/items/long-id/workbook/worksheets('Grafieken')/charts('Grafiek 1')/Image(width=0,height=0,fittingMode='fit')

Am I in the right place, and is accessing an excel file in sharepoint supported with app-only credentials, or is it possible that the URL is too long..?

@ificator
Copy link
Contributor

Hi @JWiersema, this is where some Graph magic comes into the picture. While the URL makes it look like it's hitting just OneDrive, it's actually hitting a couple of different services. If you make the following query do you get a 404?

https://graph.microsoft.com/v1.0/sites/{siteid}/drives/{driveid}/items/{itemid}

If you don't, then OneDrive itself is fine and there's most likely a downstream issue. In that case I'll see if I can track down someonw that will be able to help.

@Kid-Seven-7
Copy link

Hi, I've been trying to create a web application that allows users to access their OneDrive Accounts and upload and download files. So far I have managed to get to a point where by a user can navigate through the drive and get information on the file and folders in said drive (size, name etc), but I am failing hopelessly when it comes to the core function of the app upload download.

I make a request "https://api.onedrive.com/v1.0/drive/items/{item_id}/content" trying to download an item but I get a 401 error saying invalid auth token [Bearer realm="OneDriveAPI", error="invalid_token", error_description="Invalid auth token"]. I'm not too sure where I'm going wrong and I would greatly appreciate some assistance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests