How to authenticate to personal OneDrive with Graph REST API - azure-active-directory

I'm trying to write an R package to let users access the files in their OneDrive folders from R. The API is Microsoft Graph.
Everything is working fine with OneDrive for Business (which is basically SharePoint under the hood, as I understand it). However, I can't get it to work with personal OneDrive.
Custom app registration, consumers authorization endpoint
When I use an app registration under my own AAD tenant, I get the following error from the consumers AAD authorization endpoint:
AADSTS50020: User account 'xxxxx#gmail.com' from identity provider 'live.com' does not exist in tenant 'Consumers' and cannot access the application 'd44a05d5-c6a5-4bbb-82d2-443123722380'(AzureRtest_cli) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.
Custom app registration, 9188040d-6c67-4c5b-b112-36a304b66dad endpoint
From this page it appears that the token should be for the tenant 9188040d-6c67-4c5b-b112-36a304b66dad instead of the generic consumers. When I tried that, I obtained a seemingly valid token. However, talking to the https://api.onedrive.com/v1.0/drive endpoint results in a cryptic 401 error.
Azure CLI app registration, consumers endpoint
As a hack, I tried piggybacking off the Azure CLI's app registration. This fails with
AADSTS65002: Consent between first party application '04b07795-8ddb-461a-bbee-02f9e1bf7b46' and first party resource '00000003-0000-0000-c000-000000000000' must be configured via preauthorization. Visit https://identitydocs.azurewebsites.net/static/aad/preauthorization.html for details
Azure CLI app registration, 9188040d-6c67-4c5b-b112-36a304b66dad endpoint
Finally, I tried using the CLI app registration with this tenant, which also failed:
unauthorized_client: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
What are the exact steps I need to do to get to my personal OneDrive?

It turns out I had a bug in my code: I was using the tenant consumers.onmicrosoft.com instead of consumers. The process to communicate with Graph for personal OneDrive that worked for me was:
Use the authorization code flow as described here, with the following specs:
tenant: consumers
client id: for my custom app registration
scope: https://graph.microsoft.com/{scope} offline_access openid where the scope is one of those listed here
Use the API endpoint https://graph.microsoft.com/v1.0.
With regard to that last point, note that the documentation here is incorrect or at least outdated, as it still gives https://api.onedrive.com/v1.0 as the endpoint for personal OneDrive requests.

Related

Multi tenant SAML SSO app installed with OAuth flow?

I have a multi tenant enterprise app. It authorises a few graph API permissions when installed and has SAML SSO configured. The whole idea is that my customers can install this and in one process grant my application access to their tenant, and setup SSO for that customers users.
The graph API permissions work totally as expected, I get the needed access to the tenants who installed the app.
Then there is the SAML SSO part. That's just totally not working. In my test tenant where I installed my app, it says that the app has SAML SSO and that it is only application owner who can configure - all fine.
I then try to log in (to the web app using this SSO configuration) with a user from my test tenant - no luck!
First I thought that it had to do with the user not being assigned the app, but it complains the the application in tenant A is not available for user in my test tenant and the user should be added to tenant A. That of course is not a solution since I want to use this for customers.
So right now I am stuck with 2 app's. One gallery app for SAML SSO and my app granting API permissions. It works, but it just seems SO stupid. Isn't there a better way?
Azure AD SAML applications are not intended to be multi-tenant, this is why you need to invite external users as guests.
It's worth to mention it's possible for an Azure AD app to support both OIDC/OAuth2 and SAML and thus rely on the same session cookie to obtain an access token for MS Graph.
If you need multi-tenancy, you should use modern protocols such as OpenID Connect for authentication and OAuth2 for authorization. MS Graph relies on JWT access token anyways.

Log in user to AAD without App Registration

can I login a user to AAD without using an App Registration?
My problem is the following:
I am currently writing a python module that wraps the Power BI REST API.
Everything works fine if I register an app in AAD and authenticate via Client ID and Client Secret.
I would like to enable a user login, so that a user logs in with their credentials and can run the script with the privileges assigned to their account.
MSAL seems to support that with a PublicClientApplication and the acquire_token_interactive method. It still expects a Client ID, though.
My issue is that I would like to distribute my python module to other developers, without them having to register an app in AAD first.
After all, I can use the MicrosoftPowerBiMgmt PowerShell module without first registering an app.
How can I do that? Is there an authentication flow that does not need an App Registration?
It is not possible to authenticate user without App registration with OAUTH and OPENID connect, multi-tenant authentication means a template which will be deployed on multiple tenants with same client-id and secret

Is there a way to get a list of Azure AD tenants from within a service principal?

I have created an app to get various information from Azure AD, such as users and groups. It lives in one of my tenants as an app registration. This works fine, but now I would also like my app to get a list of the ids of other tenants I have in my account.
I have given my app user_impersonation permission on Azure Service Management, and I am able to make
GET https://management.azure.com/tenants?api-version=2016-06-01 requests using my client credentials. However, when I make that call I get a list only containing the tenant that my app/service principal lives in. Is there a way I can use this API call to see other tenant ids from within my app?
Yes, you could do that with auth code flow instead of client credentials flow.
Since you are trying to get the tenants of your account rather than the app/service principal, you have to include the account information when doing the authentication.
Client credentials flow is App-only. Auth code flow is App+user.
See reference here to learn how to implement Authorization code grant (interactive clients).
And here is the document about OAuth 2.0 authorization code flow.
You need to Request an authorization code first and then Request an access token with the code from the previous step. Using this access token, you can list the tenants you have in your account.

knownClientApplications in Azure AD App doesn't work

I have a problem with consenting to my API. I have 2 apps in my tenant (Client, API). Client app is SPA and implicit flow is enabled and it calls API, so I added Client application's id into knownClientApplications in API application. For both applications multi-tenant is enabled.
But when I try to login in my SPA from different tenant I'm only asked for Client application consent and get an error that I don't have service principal for my API application.
What should be configured in order for this to consent implicitly to API application too?
I use MSAL.js library and Azure AD 2.0. Scope: https://mytenantname.onmicrosoft.com/myservicename/user_impersonation
For the SPA application to prompt consent combined with your API consents, your scope should be https://mytenantname.onmicrosoft.com/myservicename/.default.
You can read about ./default scope here.
If you need a sample to clarify this concept, I would suggest this one

Multi tenant Daemon office 365 app registration on consumer AAD by granting admin consent, Does it also require separate registration on consumer?

I am developing a multi-tenant Office 365 daemon that requires access to user calendars.
I have successfully registered in the company tenant (Tenant1) that has deployed this app using certificates and I am able to get access tokens.
Now I created a separate AAD tenant (Tenant 2) and logged in to daemon app using administrator account of Tenant 2, it prompted the Admin Consent screen and I provided consent. There was no errors returned.
When I tried to get an app token however, I am able to get a token but with blank permissions. If I call the Office 365 API using this token, I get a 401.
I was of the view that service principal objects should be created. Also I am unable to see this app in Tenant 2 app registrations.
Do all my consumers have to register this app manually in their AD tenant and modify application manifest file to add certificate details?
I am not sure about the benefit of multi tenancy if that's the case.
I found the follow in the Azure Active Directory documentation:
The following diagram illustrates the relationship between an application's application object and corresponding service principal objects, in the context of a sample multi-tenant application called HR app. There are three Azure AD tenants in this scenario:
Adatum - the tenant used by the company that developed the HR app
Contoso - the tenant used by the Contoso organization, which is a consumer of the HR app
Fabrikam - the tenant used by the Fabrikam organization, which also consumes the HR app
You do not need to have each tenant register your application. In fact, you shouldn't since having dozens (or hundreds) of unique App IDs floating around would only create headaches for you.
Each tenant does however need to execute the Admin Consent workflow. This will authorize the App ID you've registered on your end to access the scopes you've requested.
Generally, I recommend using the v2 Endpoint and the apps.dev.microsoft.com portal for registering your app. While you can also register your app in your own Active Directory, the portal makes it a lot easier to manage.
The general process is:
Register you application in the Registration Portal
Populate the "Application Permissions" in the Microsoft Graph Permissions section.
Launch the Admin Consent workload using https://login.microsoftonline.com/common/adminconsent?client_id=[APPLICATION ID]&redirect_uri=[REDIRECT URI]
Get a beer
A couple of tips:
The Registration Portal only supports MSA (i.e. personal) accounts at the moment. I'd suggest creating a new Outlook.com account for this purpose so you can easily share the credentials with folks who need them internally.
If you create a shared Outlook.com account, you should also set up forwarding rules for all of the interested parties internally. This is in case something should every go wrong or change down the road and you need to recover the account.
I wrote a v2 Endpoint and Admin Consent primer that you might find helpful. They assume you're using the Authorization Code flow but the concepts remain the same for Client Credentials.

Resources