Single resource URI to get access token to do SSO and use Files, Calendar API - single-sign-on

We are building a Front End Application which uses Azure AD APP to do single sign-on with Office 365.
To get Access Token using OAuth authentication process, we need to pass resource URI which can be
xyz.sharepoint.com -- to integrate with SharePoint site collections
xyz-my.sharepoint.com -- to integrate with OneDrive for business
outlook.office.com -- to integrate with outlook graph.windows.net --
graph.windows.net -- to use graph API for any search.
But to finish the single sign-on process, we need to fetch the user profile information at least email id is required. We were integrating with Onedrive for business in our Front End application.
So to get the user email, I can not get this information if I get the access token using resource xyz-my.sharepoint.com. I have to use xyz.sharepoint.com or graph.windows.net. So for our requirement, we have to fetch access token for 2 resources. It does not seem right, we had to maintain these access tokens along with refresh tokens to make these access tokens active.
Is there any other way to get an access token which can be used for all office 365 services OneDrive, Calendar, Mail, Outlook and Sharepoint?
Regards,

This is exactly the problem the Office 365 Unified API attempts to solve:
https://msdn.microsoft.com/en-us/office/office365/howto/office-365-unified-api-overview
Please take a look at the MSDN page above and let me know if you run into any issues integrating with the Unified API.
I hope this helps!
Shawn Tabrizi

Related

Microsoft /adminconcent endpoint - Who authorized my app?

I have an Azure client application that uses Microsoft graph APIs.
I am using the workflow described at https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow to have admin authorize my azure client application for his tenant.
This flow ends up giving my client application an access token which my client can use to access various resources in the tenant.
Now, my client application needs to find out is 'who' provided the concent. The access token I get does not have this information (unlike in case of other authorization flows).
A tenant may have multiple admins and my application needs to know who among those admins authorized my client application.
What is the best way to find this out?
Thanks,
~ Urjit
my client application needs to find out is 'who' provided the concent.
You want to find the admin that authorize your client app, as I know, there is no way to find out this information about the admin. Because when you consenting permission for your app, you need the admin to do this for your account. After admin consent, there will be no record for this, no matter in token or portal.

OneDrive - how to access files of users in my Business account using the Rest API?

I have a corporate account with OneDrive users. I need to be able to access certain files within those users OneDrive accounts within my organization. For migration and backup purposes.
We do something similar for our Google drive and Box.com accounts where we use JWT authentication to provide a Simulate-User header which makes it so we can access all our users files within our organization if needed. As if we were administrators on a shared drive or something.
Is there a Rest API example of OneDrive JWT service account or something equivalent?
What you need is the client credentials grant flow. This will allow you to obtain an app-only token and make service calls without a user identity. You can read more about it here:
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
The scopes you will need to request are Files.Read.All, and the consent will need to be granted by the tenant admin. You can read more about the permissions required for your scenario here (application permissions is what you are looking for):
https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference#files-permissions
Here is a link to a sample Microsoft Graph project which uses app only tokens(we recommend using Microsoft Graph):
https://github.com/microsoftgraph/nodejs-apponlytoken-rest-sample
Or if you are planning on calling directly into the OneDrive API(not recommended), then you can use the following sample:
https://github.com/rgregg/onedrive-app-delegate-sample

Outlook.com REST APIs - getting a token without dynamically sign-in

Use-case: Emails to be sent from a web-application upon an event, as someuser#somedomain.com via MS Exchange or Outlook.com, using the RESTful APIs exposed by Outlook.com. Only HTTP access allowed (=> no SMTP/IMAP).
All documentation seems to mention that the app has to forward users to MSOnline, sign-in and then use the authorization code sent back by MS online.
But, this won't work for a background task (=> no sign-in possible!) where a pre-built token(with some predefined scope) is necessary so that Outlook.com can be accessed via APIs to send mail as someuser#somedomain.com.
Any hints/pointers to how it could be done? Basically, automated authentication without explicitly signing in as 'someuser#somedomain.com' on the MS Online login page.
I did not find M$ documentation regarding Outlook REST APIs to be of any great help and found it to be pretty difficult to navigate/understand. :(
Thanks!
At some point you will have to have the user sign in to grant access to your app. So you would need to have some sort of user-facing web front end where they can do this. Once they have signed in and you've obtained an access token/refresh token, your background app should be able to use those tokens silently, without user interaction, at least until the user either revokes access or the refresh token expires.
Currently Azure (which provides the login/token functionality) does expire the refresh tokens after some time (90 days), at which point the user must sign in again to grant your app continued access.

SharePoint Error using Office 365 REST API OAuth access_token

I am developing a rather simple application that retrieves files from SharePoint using the REST Office 365 API. This is a batch job running in the background with no user interface so the following simple 2-step flow is what I'm doing:
(1) Requesting an Access Token from Azure AD (supplying client ID, client secret, resource, and grant_type=client_credentials)
(2) Invoke the SharePoint API (https://{base url}/_api/v1.0/Files) using the "Authorization: Bearer " as a request header .
That process seems pretty straightforward and sounds simple but I keep getting the following error:
401 Unauthorized
x-ms-diagnostics: 3001000;reason="There has been an error authenticating the request.";category="invalid_client"
Any idea what the problem is and how this can be resolved ? I have been stuck on this for days now. I would REALLY appreciate somebody's help with this. Thanks.
SharePoint Online doesn't yet support clients accessing it using app-only tokens (resulting from client credential OAuth2 flow). It only supports delegated token aka user+app tokens (resulting from authorization code OAuth2 flow).
So, if you wish to write a client application (web app or native client app) that accesses SharePoint online - it can only be on behalf of a user, and it must involve interactive authentication of the user - after the user authenticates - they will be shown a consent page where they need to consent to your application accessing the O365 API on their behalf.
Only Mail/Calendar/Contacts APIs (Exchange Online) support clients accessing them using app-only tokens - and they have turned on this support very recently. Read about client credential flow tokens with Exchange Online APIs here: http://blogs.technet.com/b/ad/archive/2015/02/04/using-azure-ad-to-build-daemon-applications-that-call-office-365-apis.aspx, http://blogs.msdn.com/b/exchangedev/archive/2015/01/22/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx
Hope this helps.
ps: OAuth2 client credential flow doesn't issue a refresh token
You will need an access token for the specific resource you are trying to access - in this case your sharepoint site for the Office365 REST Apis.
A good read on this can be found here: https://msdn.microsoft.com/en-us/library/azure/dn645538.aspx
Assuming your {base_url} is a sharepoint site, i.e., 'https://[site_name]-my.sharepoint.com
You can either:
(1) Initially get the access and refresh tokens using your client credentials plus a resource = {base url}
or
(2) Once you have the access and refresh token from the Azure AD resource, make a refresh_token call using:
client_id
client_secret
grant_type = 'refresh_token'
resource = {base_url}
refresh_token = [refresh token received from Azure AD
generate token response]
In this case you'll have 2 access tokens:
one that can be used for Azure AD requests
one that can be used for Office365 REST Api requests.
We could not/have not found a way to have a single access token be 'valid' for more than 1 resource.
Hope this helps!

Office 365 OneDrive REST API - "invalid_client"

I'm trying to make a call to the new Office 365 File REST APIs. (As explained here).
I'm using Postman rest client to send the request.
I have registered my application in Azure AD and given it full permissions to 'Office 365 SharePoint Online'.
I can successfully get an authorization token using the clientId generated in Azure AD.
However when I attempt to list files, using the access token I get an error.
------------------
RESOURCE HTTP GET:
------------------
URL: https://<OUR_DOMAIN>-my.sharepoint.com/personal/<user_domain>/_api/Files
HEADER: Authorization: Bearer <access token>
Response:
3001000;reason="There has been an error authenticating the request.";category="invalid_client"
What can cause this issue?
Not sure what steps you've tried to use to resolve this, so it's hard to help you out here. I've just finished writing up more detailed instructions on the steps to register an app to call OneDrive for Business. It's long and complicated right now, but we're working to make things better in the future.
You can check out the details of how to do auth here: https://dev.onedrive.com/auth/aad_oauth.htm
Make sure you aren't asking for too many permissions, since that will require your app to be authenticated by an admin instead of the end user. For most apps, you can just use the "My files" permission scopes which can be accepted by the user of your app directly.
If you post more information about what calls you're making, responses, and app configuration in AAD I might be able to help more.
You may have been using different resources.
Check whether the resource which you have used for getting access token is same as which you are requesting for getting files.
for example :
If the resource which you have mentioned while requesting access token be :: "https://tenant-my.sharepoint.com/"
Then you need to make request on the same resource for accessing files :: "https://tenant-my.sharepoint.com/_api/v2.0/drive/root/children"
The above request give list of root children.
tenant --> domain name which was registered to your organisation.
Follow this documentation for further accessing the api