OAuth 2.0 Implicit Grant flow - Read calendar API returns 403 - oauth-2.0

Can anyone help me to figure out solution for the below problem?
Summary:
I am getting 403 for Microsoft Graph Calendar Read API.
Detail
I am using microsoft identity platform with implicit grant flow mechanism to log user from his microsoft account into my application.
I am requesting in scope parameter with these permissions "profile User.Read Calendars.Read Calendars.ReadWrite"
Below things works after successful login.
1) It asks for the permission to grant
2) Microsoft oauth2.0 login.
3) Profile picuture read.
But for some reason when i try to read "calendar" I get 403 for only one account in whole tenant. I have gone through below link for error description, but couldn't find out solution
https://learn.microsoft.com/en-us/graph/errors
can anyone point me, where i need find solution for the above issue? Is it account issue or do I need to modify api request. Below api i am using to read calendar
https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=${sd}&endDateTime=${ed}

For this problem, first you need to check if the token you got contains the correct permission, you can decode your token in this page. I test request this graph api with implicit grant flow, it works fine and I put my access token to decode we can see it contains the two calendar permissions which we expect.
Here I list some points which you need to pay attention to when you request this graph api:
1. As you mentioned in your question, you request in scope parameter with "Calendars.Read Calendars.ReadWrite" permissions, so did you add these two permissions to your AD application ? If you didn't add them, please add them in your AD application (please add them in "Delegated permissions" but not "Application permissions", I test it if we add them in "Application permissions" it will show 403 error because implicit flow requires "Delegated permissions").
2. After add the two permissions, don't forget grant admin consent for them.

Related

Does Microsoft Graph work without User.Read scope?

My question is, does Microsoft Graph work without User.Read scope ? I am not able to request the email profile openid permissions directly.
It throws AccessDenied error. So is User.Read pre requisite for email profile or openid ?
User.Read is just the delegated permission for getting the user profile using MS Graph Get User. If your app does not need to read the user profile you don't need this permission but in most cases you do because you app is acting on behalf of the user.
Does Microsoft Graph work without User.Read scope ?
No, but in most cases, you need the scope to read user profile and call /me endpoints.
You should check the api document to see if calling that api required User.Read permission.
For instance: I wanna call this api to list emails, and we can see that this api provides 2 kinds of permissions, one is for delegate, another is for application(this means client credential flow is supported). All the api permissions are listed here and we need to go to azure ad portal to add the api permission to your azure ad application which used to generate access token.
After generating the access token, you can user jwt decode tool to check if your access token contains correct scopes(for delegate permission) or roles(for application permission). Using a correct token to call the api will not lead to AccessDenied error. By the way, newly added permission may be deferrable to take effect.

Daemon application gets an App-only access token with no Roles

I have a JavaScript app that requires a user to login and hit a button then it runs a report, posts data to Excel, and sends an email. I want to automate this so a user does not have to log in and push a button.
I started with this project code: https://github.com/microsoftgraph/nodejs-apponlytoken-rest-sample
I followed the instructions and am able to get an access token but then my api call fails with 401 unauthorized. As a test, I am trying to send an email as myself and I have the Application type Mail.Send permission granted by the company admin.
I have spent many hours reading docs and blogs but have not found a solution. This document summarizes best what I am troubleshooting: https://blogs.technet.microsoft.com/sharepointdevelopersupport/2018/03/15/troubleshooting-assistance-with-microsoft-graph-api-development/.
The token I get back does not have any Roles in it as seen when I decode it with JWT. This is the only discrepancy I have found so far.
Any advise would be greatly appreciated. How can I ensure that my token has Roles defined or what else can I try? How is it that I can get a token successfully but can't use it for anything?
Thank you!
I am not a Node expert, so helping you out with a few pointers that might help.
Microsoft Graph has two types of permissions, Delegated and Application. So some things to know of and check..
Delegated permissions require a user to be present, they would show up in the scp claim in the access token. These are obtained by web applications using the implicit_grant flow, Authorization code grant or on-behalf-of flow (usually).
Application Permissions, require an admin to consent and will be provided to you in the roles claim in the access token. This requires, the app to obtain an access token via the client credentials grant. Note that, these are also present when the user is assigned a role as explained in this sample, but this scenario might not be applicable for in your case.
Does you app has the grant provided as you expect? You can check these via the Graph Explorer using the following two rest calls. There would be a OAuth2PermissionGrant entry with the expected role in it.
https://graph.microsoft.com/beta/OAuth2PermissionGrants
https://graph.microsoft.com/beta/kalyankrishna.net/OAuth2PermissionGrants
It'd help more if you can explain the flow that you have been using to obtain the access token. For example, the implicit_grant_flow does not work with application permissions.
In my case, the problem had to do with the endpoint and my tenant. I had been using the common tenant make api calls for tokens because that is what was listed in AzureAD for my app. I found that for the Application client permissions I must use my specific tenant id like 'https://login.microsoftonline.com/tenant_id/oauth2/token' when getting tokens with the proper roles.

Microsoft Graph returns "The token contains no permissions, ..." when using app-only token

Using Postman, I am trying to retrieve the last emails received in my Outlook mailbox.
To achieve this, I have declared my app in the App Portal. Then, I can do a GET request to get a token from the endpoint:
https://login.microsoftonline.com/[tenantId]/oauth2/token
Next, I try to use the token I received to perform a request at
https://graph.microsoft.com/v1.0/me/mailfolders/inbox/messages
The problem is that the API returns:
{
"code": "NoPermissionsInAccessToken",
"message": "The token contains no permissions, or permissions can not be understood.",
}
In the permissions of my app, I have authorized every action related to reading emails. Am I missing something?
I was actually missing admin approval for the scopes (read.mail in my case). In a App-Only usage, you need to get approval from admin. To do so, admin must use this url:
https://login.microsoftonline.com/common/adminconsent?client_id=[your_client_id]&state=[random_string]&redirect_uri=http://localhost/
Admin will be prompt to approve permissions.
This sounds like you forgot to "Grant permission" (it happens to the best of us :P).
Grant the permission for your tenant. The easiest way is through https://portal.azure.com -> Azure AD -> App Registrations -> Your App -> Settings -> Required permissions -> Button Grant Access.)
Related to this answer
It also helps to take the token, and paste in into https://jwt.ms which will show you all the data in the token (and should also show the claims about the granted permissions).
The exception is the API to find meeting times or send mail, which applies to only Office 365 mailboxes (on Azure AD) and not to Microsoft accounts.
For simplicity of reference, the rest of this article uses Outlook.com to include these Microsoft account domains.
https://learn.microsoft.com/en-us/previous-versions/office/office-365-api/api/version-2.0/calendar-rest-operations

Microsoft Graph API .NET not able to read shared mail

First post...here goes. I am trying to display email from a shared mailbox but run into "ErrorAccessDenied Access is denied. Check credentials and try again".
The user does have permission to the mailbox, I can access/read email in Outlook and in O365 portal. In my app I have also assigned Mail.Read.Shared and Mail.ReadWrite.Shared scopes.
At first I tried Graph Explorer
https://graph.microsoft.com/beta/users/<userPrincipalNameOfSharedMailbox>/messages
but same ErrorAccessDenied, assumed Graph Explorer did not have Mail.Read.Shared scope.
Next I tried to modify Microsoft Graph Snippets Sample for ASP.NET 4.6
I added Mail.Read.Shared and Mail.ReadWrite.Shared and was prompted to accept these permissions
• Read and write mail you can access
• Read mail you can access
but I get the same error when I try get mail from the shared mailbox
IUserMessagesCollectionPage messages = await graphClient.Users["userPrincipalNameOfSharedMailbox"].Messages.Request().GetAsync();
There was a similar post here Microsoft Graph API SDK .NET Issues getting other users emails and the answer implies this is possible. If it is can anyone provide some insight as to what I am missing? thanks
Right now, accessing shared messages is not supported for the authorization_code flow, but it is supported for the client_credentials flow. In order to incorporate this functionality, you will have to change your flow to incorporate this.
Here is an article on creating a client_credentials flow app if you are interested in going this route.

Does Google OAuth2.0 support an OAuth-flow for a Resource Owner Password Credential Flow?

Hello kind people of the internet.
Does Google OAuth2.0 support an OAuth-flow for a Resource Owner Password Credential Flow?
...and if so, then:
A.) can this type of OAuth flow be tested on the Google OAuth2 Playground?
B.) are there any examples of the "Resource Owner Password Credential Flow" with Google OAuth2.0 and the Google APIs?
Per an OAuth presentation recently in Oslo NDC 2013, this subject flow apparently skips the authorization end point all together and directly talks to the token end point of the OAuth2 server. The request syntax incantation would supposedly look something like this:
grant_type=password&
scope=resource&
user_name=owner&
password=password&
My understanding is the Resource Owner Password Credential Flow is for trusted applications in a back-end enterprise type of situations (where a name-password pair could be securely stored).
This particular OAuth flow would require no end-user consent interaction (no pop-up of a browser to Accept, then get a returned authorization-code, etc). In this subject flow the access & refresh token are directly returned, again: with no end-user interaction (albeit after an entry of a username-password).
Looking through the Google OAuth documentation ( link to Google OAuth2 docs ) there does not seem to be any mention of anything resembling Resource Password Credential Flow, but not sure that necessarily means it is explicitly not supported by Google.
Any help or advice would be much appreciated.
thanks in advance
Dear kind internet person,
it is true that Resource Owner Password Credential Flow is not supported on Google but google suggests you use the Installed Application Flow, which is described in: https://developers.google.com/accounts/docs/OAuth2InstalledApp.
You would need to create an Installed Application in the Google Console (https://code.google.com/apis/console), when you do that you can fetch the client_id and build a GET request with the parameters, which would look like so:
https://accounts.google.com/o/oauth2/auth\?
scope\=<scope>\&
redirect_uri\=urn:ietf:wg:oauth:2.0:oob\&
response_type\=code\&
client_id\=<client_id fetched from google console>
You would construct this URL and navigate to it on your browser, allow access for the app and google would give you what I believe is a code which you can use to get credentials. You can use those credentials to get an access token and refresh it, and this credentials is permanent. There's a good example of that on github. Note that you only need to get those credentials manually once, and then you save those credentials somewhere and keep using them to get/refresh tokens.
Hope this helps!
As far as I know, No. The OAuth 2.0 stuff is for Google accounts, for which Google does authentication.

Resources