Refresh Token not Working in Microsoft Graph APIs - asp.net-mvc

I have been using Microsoft Graph APIs in my .NET application to read Calendar, mails and Contacts from Office 365. Now my application uses Access Token for its working, which expires after every one hour and prompts the User to re-login.
My requirement is to extend the token expiry, which can only be done using Refresh Token. I tried to include the scope "offline_access" in my app and it gave me the error "MSAL always sends the scopes 'openid profile offline_access'. They cannot be suppressed as they are required for the library to function. Do not include any of these scopes in the scope parameter."
I have modelled my application on the demo given by Microsoft for Graph APIs and MVC integration on the link:
https://learn.microsoft.com/en-us/outlook/rest/dotnet-tutorial
What wrong am I doing here or what am I missing?
Any help would be greatly appreciated.

The tutorial you are referring to is for the Outlook REST APIs. NOT Microsoft Graph. All Microsoft Graph samples are here https://developer.microsoft.com/en-us/graph/gallery/?filterBy=Samples,SDKs
There is a great getting started page that links to a tutorial to build your first app https://developer.microsoft.com/en-us/graph/get-started/asp.net
This uses MSAL v2.7 SDK that handles the refresh tokens for you and the Microsoft Graph SDK for dotnet.

Related

Access Microsoft graph resources with an auth0 login

I'm having difficulties finding documentation for auth0 and microsoft graph integration. My end goal is to have a SPA that can login with a microsoft profile to auth0 (connected to azure ad). Then I want my app to get a token for microsoft graph and do some api calls.
As I've understood it so far, auth0 does not allow you to get the access token to different identity providers in a front end application, but rather that they should use a proxy to get this token. My flow therefore is:
I login with a SPA auth0 app (using a microsoft identity)
This is then used to authenticate to a backend server using a api registration in auth0
The backend has its seperate machine-to-machine app in auth0
Backend api uses this seperate app to get access token to auth0 management api
Current user is fetched (based on the logged in user from front end app login) from management api,
Here i find an access token under the azure identity (if I do the same in the front end, the access tokens are omitted)
Token does not work to call graph, I am unsure of where to send it next.
I am aware that the above is probably completely wrong, that's why I am here :)
My questions are:
1) Is it even possible to get an access token for microsoft graph starting from a login to auth0 in the way I want it to. If not, can it be done from a backend?
2) Does anyone have a link that discusses this, ideally with some code samples.
To answer your first question:
1) Is it even possible to get an access token for microsoft graph starting from a login to auth0 in the way I want it to. If not, can it be done from a backend?
I have had the chance to authenticate apps using the microsoft identity library called MSAl whose documentation is found here. It gives a pretty detailed way to authenticate directly from your SPA.
I have also used the microsoft javascript sdk as it comes inbuilt with token caching and refreshing so that I do not need to build that for myself.
In relation to this,
Does anyone have a link that discusses this, ideally with some code samples.
You can find the samples well described in the samples section of the SDK
I hope this helps.

Which authentication library to use with Node.js for all Microsoft accounts

I'm trying to create an Amazon Alexa service that will take advantage of the Microsoft Graph... This is built with Node.js.
Currently when using my standard Outlook.com Microsoft Account to sign in, I get redirected to a Microsoft page that says
Microsoft account is unavailable
Microsoft account is unavailable from this site, so you can't sign in or sign up. The site may be experiencing a problem.
You can sign in or sign up at other Microsoft Sites and services, or try again later at this site.
I have been using https://login.microsoftonline.com/common/oauth2/v2.0/authorize as my authorization URL in the Alexa config account linking section. and using the Node Microsoft Graph JavaScript SDK library in my code.
I'm wondering if the Node library I'm using is the correct one? Has it been deprecated? Or is there something else going on here?
A common misunderstanding with Microsoft Graph is the separation of concerns between the API and Authentication.
You do not actually authenticate against Microsoft Graph. Instead you authenticate against the directory that holds your account, for organizational accounts this is Active Directory and for consumer accounts this the Outlook.com.
Once you have authenticated, you use the token you received back to identify yourself when calling Microsoft Graph API.
This is where you (and many others) get tripped up at first. Just as there are two concerns (Auth & API), there are also two separate SDKs. For Node.js you're looking for:
Microsoft Authentication Library (MSAL): This handles authentication for both Azure AD and Microsoft Accounts.
npm install msal
Microsoft Graph JavaScript Client Library: This is the client library for Microsoft Graph. It will provide the objects and methods you need to simplify calling the APIs.
npm install #microsoft/microsoft-graph-client
This should give you the tools you need to get started. There are some things around App Registration, OAUTH and Admin Consent that you'll likely run into as well. For these, you might find these helpful:
Microsoft v2 Endpoint Primer
v2 Endpoint and Implicit Grant
v2 Endpoint and Admin Consent
Hope this helps!

Microsoft Graph Authentication Token Issue

I am new to Microsoft Graph and SharePoint Framework. Recently developing spfx webpart with Graph API's integration.
I have registered the app in https://apps.dev.microsoft.com portal and AAD implementation through hello.js.
The first time browsing to the page, it redirects to Microsoft app login page and prompt for credentials.
Once authentication successful then it's working fine, from then on it does not prompt for credentials.
Is there any possiblities to access MS Graph API directly using Application Id, and Secret without prompting for login?
Yes, you will want to use the client credential flow to do this. You will only have access to organizational data (/me won't work for example, but /users will). There is an article on getting access here.
You will need to log in as an admin one time per application to authorize your app to use your tenant's data. You can do this at:
https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions

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.

Accessing Calendar, Mail and Contacts of an OAuthenticated user

I configured an application on AzureAd to be multi-tenant, I chose to require all the permissions for Windows Azure Active Directory and Office 365 Exchange Online.
I can get a user to grant permissions, get access tokens, refresh them, OAuth works for me. I always used the "common" keyword instead of the tenant ID, because my app is multi-tenant.
Now, I would like to have (CRUD) access to a user's Mail, Contacts and Calendar with this token. Here is my problem: I am completely lost in all the possible API endpoints. Should I use: graph.windows.net, outlook.office365.com, graph.microsoft.com? This page seems to suggest that graph.microsoft.com is the Swiss army knife that would serve my purpose, but somehow I cannot find a doc that allows me to find the info I'm looking for. Plus, it seems under development and maybe too incomplete for what I want.
If I make queries against outlook.office365.com, I've got a 401 error.
If I put my access token in this token analyzer, it seems healthy although the scope field only shows the permissions I set in the AzureAd portal for Windows Azure Active Directory, not Office 365 Exchange Online.
I am kind of lost, any help would be welcome...
You have a choice:
Call the separate service apis - Your problem is that you acquired a token to call AAD, and then tried to use that to call Outlook - you need to make a separate call to acquire a token for outlook.office365.com through ADAL or through the token endpoint directly. The token acquired for AAD Graph can ONLY be used against AAD Graph. Similarly the token acquired for Outlook can ONLY be used against Outlook APIs.
Just to clarify - Azure AD OAuth can protect/secure multiple web APIs, including O365 APIs, Azure AD Graph, Azure Resource Management APIs, your own APIs and the new O365 unified API. In the first access token request, you specify the first resource you want/need to call. It doesn't have to be AAD Graph - i.e. it's not the default AFAIK. Based on what is consented to, you have the ability to request additional access tokens using the (multi-resource) refresh token. Vittorio's blog post which you link to in your comments does a great job explaining this.
Call the O365 unified API (which is in preview) and IS documented. See below. The beauty of the unified API is that you only need to acquire a token to call graph.microsoft.com and ALL the entities on that endpoint are available to you AND more. It removes the siloed nature of #1, and the requirement to get and manage multiple access tokens to call these different API endpoints. However #1 is currently GA, and the unified API is preview only at this time.
For more on #2 please see https://msdn.microsoft.com/en-us/office/office365/howto/office-365-unified-api-overview and search for "unified" in the list of samples here: https://msdn.microsoft.com/en-us/office/office365/howto/starter-projects-and-code-samples
We are working on improving the unified API documentation. If you are making pure REST calls, then I recommend starting out with the API explorer (and try things like https://graph.microsoft.com/beta/me/events and https://graph.microsoft.com/beta/me/messages to get your calendar events and mail messages), OR the API sandbox (which can show you JS code snippets, and allow you to test your own easily enough). As you can see on the REST examples, to access mail and calendar features in the unified APIs, you should be able to swap the service roots from Outlook to the unified API ie - https://outlook.office365.com/v1.0 -> https://graph.microsoft.com/beta. On the JS sample - we will be adding more capabilities here and additional samples.
NOTE: Personal contacts available in outlook.office365.com are not available in the unified API yet.
Hope this helps

Resources