Authorize non admin account to access OneDrive for Business files - microsoft-graph-api

I want my application to access my users OneDrive for Business files (both read and write access). It should work as an alternative browsing client, so the user just has to login and then browse his files.
With personal OneDrive using the v2 Endpoint, it works flawlessly.
When I try to login my OneDrive for Business account I get an error stating that my application requires some privileges that only Admins can grant.
But.. From the app panel ( https://apps.dev.microsoft.com ) my application requires only permission that non-admin users can request (under delegate authorization). The Application authorization list empty.
I also tried to remove ALL the permission required, save, wait some minutes and retry.. and even without any permission required i still get the same error.
I tried making new application, checking all the permission, refreshing the app's key.. but i always get the same error. If i try to login the same account from other commercial application it works.
I also don't have access to any admin account to see a list of authorization required by my app.
I'm really out of ideas, what i can try?

Related

"Error 403: access_denied" when usign Google OAuth

I am trying to understand the basic logics for receiving GMail emails with Google OAuth. I see this document Authorizing Your App with Gmail
Now I follow the instructions in Setting Up POP3 Importing with OAuth via Google to setup POP3 with Google OAuth.
I login one Google account(Account1) and then in Google Cloud, create the Google App and OAuth Client ID.
Then I start connect to GMail account(Account2) with the web application(WHMCS). When connecting, it asks me to choose an account that create the app, so I choose Account1. But get the following error:
Error 403: access_denied
The developer hasn’t given you access to this app.
Thus I am a bit confused. Since Account1 is used to create the app and OAuth Client ID, it should be able to access the app when I choose Account1, but the app will not be able to access the data in Account2. Or does the App in the error message means Gmail, not the app I created in Google Cloud?
Should I use Account2 to create the app for receiving emails in Account2? If yes, then for each Gmail account, should I create a separate app accordingly?
Update
Now I try to do as follows:
Use Account3(The admin of Google Workspace) to create the Cloud Project, Consent Window, Client ID, etc.
Then when connecting from WHMCS on our domain datanumen.com, it asks me to choose the account, I choose Account3, and then see a new window as below:
I then select "Allow" button, but then see the following error:
Connection unsuccessful. Please close this window and try again.
Update
I try several times. And find the first time will be successful. I forget enable POP3 in my Gmail account. After enabling it, everything is fine.
I am a bit confused as to what you are trying to do here.
You created a project on Google cloud console and created client id and client secret for the authorization of your project.
All this does is create a project that will be allowed to use Oauth2 to request authorization of a user to access their data.
If I understand what WHMCS is trying to do. Its going to let you use your client id and client secret to request access of a user to access their data.
So when it asks you to authorize a user this is the user whos data you want access to. That user must be added as a test user over on Google cloud console for the project that you created.
The project you create on google cloud console is still in the testing phase. Each user you want to allow to test your application must be added as a test user. Other wise only the owner of the project can test the applicaiton.
To fix this issue for me was this simple:
Go to https://console.developers.google.com/
open the project in question.
Click "OAuth consent screen" on the left.
Under "Test users" there is a button called "+ ADD USERS"
Type the email of the account you will be testing with, press enter, then click save.
It should work now
It seems like they updated this recently because last year I did not have to do this.
workspace
The issue you may be having is that if you created this project on a workspace account then i suspect only workspace domain users are going to be able to authorize it. It cant be authorized by someone on the standard google domain. So try with a workspace domain user. The same may go the other way I have never tried tbh. I tend to keep workspace within its domain.

What API permission is needed when enabling User assignment required? in Azure AD Enterprise application

If in Azure portal, I set Enterprise applications > Properties > User assignment required? to No, then authentication works as expected. However, if I turned it on, users get error Application needs permission to access resources in your organization that only an admin can grant. I understand that I need to add an API permission to my app, but what is it?
Interestingly, if a user has signed in into the app before, then they are not affected when turning the option on. Only users who have never use it are affected
Edit: To clarify, I already have App roles created. Users without app roles can't sign in, as expected. Users WITH app roles who sign in for the first time after the the option turned to Yes get the above error
Finally, I reproduce your issue with the request URL below, the scope also could be another one, e.g. https://storage.azure.com/.default, which has been added in the API permissions of the AD App.
https://login.microsoftonline.com/<tenant0id>/oauth2/v2.0/authorize?
client_id=xxxxxxx
&response_type=code
&redirect_uri=http://localhost
&response_mode=query
&scope=https://management.azure.com/.default
&state=12345
If the User assignment required is set to Yes, I notice it will not promote the user to consent the permissions. (e.g. user_impersonation in the Azure Service Management API.)
To fix the issue, we need the admin consent to the App, just navigate to the API permissions, click the Grant the admin consent for xxx button, then it will work fine.

Adding new permissions resulted in: Access is denied. Check credentials and try again

I made an app where the user logs in to their Office 365 account and I perform actions using the Microsoft Graph API. When I first started the app, I requested for little permissions such as profile and mail permissions. However, I now want to access the user's calendar and thus I added more permissions (Calendars.Read, Calendars.ReadWrite).
Now, when I try to get the user's calendar events, I receive the following error:
{code: ErrorAccessDenied, message: Access is denied. Check credentials
and try again., innerError: {request-id:
33074527-630e-41cf-bd00-4fcd5f0ac816, date: 2018-09-10T03:15:07}}
I noticed that once I added these calendar permissions, it didn't prompt the user to accept these new permissions so I think that's why I don't have access. Do I have to delete my app or something in order to get these permissions from the user? I tried to force the user to sign in again adding new permission requests to the scopes variable but it still didn't ask the user for these permissions.
No, you need to update the consent recorded for the user. My guess is you are using the Azure v1 OAUth2 endpoints, as this problem tends to crop up there more often than the v2 endpoints :).
The problem here is that the first time your user consented, Azure recorded their consent so they wouldn't be prompted again. That record captured the permissions you initially had configured on your app registration. Azure v1 is not "smart" enough to detect that you've added new permissions on your app registration since the user's consent was recorded, so it happily continues to issue tokens with the old permissions, skipping the user prompt.
To get the prompt to show up, you need to include a prompt=consent query parameter on the authorization URL, as documented here.
If you're using the v2 OAuth2 endpoints, this becomes a bit easier. With the v2 endpoints, all you have to do is include the new permission scopes in the scope query parameter for your authorization URL. Azure will detect that the user hasn't consented for them, and will prompt.
So how do you tell which endpoint you're using?
Did you register the app at https://portal.azure.com? You're using v1.
Are you using ADAL libraries in your code? That's v1.
Are you using MSAL libraries? That's v2.
Does your code send the user to a URL that has v2.0 in it? You guessed it, that's v2. If there's no v2.0 in it, it's v1.

Can't get permissions for Microsoft Graph API Drive integration

we are using Microsoft Graph API for uploading files for business and personal accounts.
After the account logs in, we ask for some permissions, but we don't add the once needed for OneDrive. After the user explicitly requests to upload a file we send another request for an AccessToken including all scopes until now + files.readwrite.all. This was working perfectly until (maybe) a month ago. Now it works for business accounts, but not for personal accounts.
Steps that we do:
Redirect the user to login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=...&redirect_uri=https%3A%2F%2Fmywebsite.com%2Fsignin-microsoft&response_type=code%20id_token&scope=openid%20offline_access%20profile%20email%20mail.readwrite%20mail.send%20contacts.readwrite%20calendars.readwrite%20people.read%20user.read%20files.readwrite.all&response_mode=form_post&nonce=636656...&state=CfDJ8MLMcPchE...
The user selects their account (whit which they are already signed in)
They get redirected to https://login.live.com/oauth20_authorize.srf with the following sreen:
The permissions are not added for our application and we don't get any error.
Here is also the response from the error page:
Error Info
"/pp1600/oauth20_authorize.srf?client_id=9d3c...&scope=openid+offline_access+profile+email+mail.readwrite+mail.send+contacts.readwrite+calendars.readwrite+people.read+user.read+files.readwrite.all&redirect_uri=https%3a%2f%2fmywebsite.com%2fsignin-microsoft&response_type=code+id_token&state=CfD...&response_mode=form_post&nonce=636...&x-client-Ver=5.2.0&display=host&uaid=521...&msproxy=1&issuer=mso&tenant=common&ui_locales=en-US&username=pesho..."
loginserverprotocolhandler(846)
HR=0x80041018
Method string:GET
URL:"/pp1600/oauth20_authorize.srf"
Query string:"code=5"
Server protocol:HTTP/1.1
Update: after a couple of tries i actually managed to grant access to one of my accounts for the OneDrive integration. Not really sure what changed. I was just logging in and out with different Outlook accounts in Outlook and in our app. After that, i tried the same process with a different account and it failed again. Every time I was trying this I was logged with the same account on both places.
One more thing that I noticed is that before the consent was for all permissions and now the consent screen showed request only for the files permission.

How do I test a Azure AD protected Web API in with Visual Studio Test Adapter?

I've created a multi tenant Web API that works just fine. Now I want to build a native client for testing. The Web API app is defined in one tenant. The test app is defined in another tenant that has given admin consent to the Web API.
I want to use the native app to authenticate with username and password in my (non-interactive) integration tests. I cannot use certificate/app-only authentication because I need a real user context.
Getting a token
var userCredential = new UserCredential("admin#clienttenant.onmicrosoft.com", "password");
var context = new AuthenticationContext("https://login.windows.net/common");
return context.AcquireToken("https://webapitenant.onmicrosoft.com/webApiResourceUri", testClientId, userCredential).AccessToken;
The problem with this code is that it doesn't work until I've given admin consent to the native app, even if the user is in the same tenant as the app registration.
Exception thrown:
'Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException' in Microsoft.IdentityModel.Clients.ActiveDirectory.dll
Additional information:
AADSTS65001: The user or administrator has not consented to use the application with ID 'nativeclientid'. Send an interactive authorization request for this user and resource.
Since tests aren't interactive I have to create a console application that uses the above code but with PromptBehaviour.Always. This will prompt me for username and password and show a consent form. After I give consent the tests that is using the same native app registration starts working.
Is there a way to accept the consent form without a interactive GUI?
At the moment there is no other way to write user consent without some sort of user experience. (Which makes sense right?)
If you use the Azure Management Portal, as an administrator of your tenant, all the apps you create should automatically be consented for the resources you selected. This is because the Azure Management Portal specifically will write those consent links as you save your client application.
If you use other portals or APIs to create your application, then you will need to consent to the application at least one time. You do not need to necessarily put prompt behavior on your application to get the consent screen. You can just generate the URL for signing into your application, which will also take you through the consent experience:
https://login.microsoftonline.com/<TenantID>/oauth2/authorize?client_id=<AppID>&response_type=code&redirect_uri=<RedirectURI>&resource=<ResourceURI>&prompt=admin_consent
Note that we added a "prompt=admin_consent" at the end which will consent to the application on-behalf of the whole tenant. With this kind of consent, you will only need to do it once per application to get it working.
I hope this helps!

Resources