How to get an "until-revoke" refresh token under Outlook API? - azure

I have clients connecting to my backend application giving me permissions, access token and refresh token but these refresh tokens have a limited lifetime if not used and from this, comes the need for the client to revalidate the permissions and tokens.
To avoid that, I'm trying to find ways to have an "until-revoke" refresh token for the OAuth under the Outlook API. I'm not being able to find much information about this. There is something related to Azure policies to change that but... I haven't found a way to do so and specialy related/connected to Outlook API.
Do I have a solution for this or do I need to setup some kind of cron to update the refresh token before expiring?

You're backend application should receive until-revoked refresh tokens if it is configured as a confidential client.
you can see how an application is configured as a confidential client in Azure AD in this article.
Hope it helps!

Related

Obtain SharePoint specific access token for a non-user application

I am working on a PHP web app that needs to make HTTP requests to the Sharepoint API with Sites.Selected permission to a specific SharePoint site. It is NOT viable for me to provide a user sign-in experience so I need to treat it as a non-user/daemon application.
I've read the docs and looked at many different forums for the solution but as of yet I've been unsuccessfull in obtaining a SPO specific access token, although I think I'm close.
I am using this StackOverflow answer as a guide: https://stackoverflow.com/a/63386756/19038862
This is what I've done:
Registered an Azure App: (Image of my Azure App Overview)
Created a client secret in the App dashboard: (Image of the client secret page)
Successfully sent a request to https://login.microsoftonline.com/{{app_tenant_id}}/oauth2/v2.0/token using the client secret in Postman: (Image of Postman request)
The request made in step 3 returns an access token (I assume a MS Graph access token?), but it DOES NOT return a refresh token, which is what the afforementioned StackOverflow answer suggests you need to "swap" for an SPO specific access token.
How do I obtain this refresh token so that I can swap it for a SPO access token? Or what better way is there to get my hands on a SPO specific access token from a non-user app?
I wrote this gist to guide you into getting Sites.Selected access to the desired site:
https://gist.github.com/ruanswanepoel/14fd1c97972cabf9ca3d6c0d9c5fc542
This guide shows you how to configure this as Application permissions, and via the Graph API.
I've found going through the Graph API is the best way to go.
Also strangely it's not possible to get delegated Sites.Selected permissions. You must set it up as an Application permission.
In the guide is described that you have to get a delegated auth token from graph but you are getting an application auth token. The token response of this flow does not contain a refresh_token. See here.
But you already wrote that you are not able to provide a user sign-in experience. One workaround would be to once manually get the access_token and refresh_token of a user with the delegated flow and then periodically get a new access_token with the refresh_token on your server. You could store these values in your database and update them when you fetch a new one.
First, the daemon-based client credential flow does not return a refresh token for you. You also can't redeem the refresh token of the graph API for an access token for SPO, which are two completely different API resources.
To get an access token for SPO you just need to set scope to: https://{tenant-name}.sharepoint.com/.default.

NodeJS application to use quickbooks Oauth2.0 and stay log in

I was able to implement a NodeJS application to sign in with my quickbooks developer account using OAuth2.0.I have the client key and the secret key and I am able to get the access token by signing in to quickbooks with their pop up and it redirects me to my application, and then the user is able to send invoices or get data from this quickbooks account.
However, I want the user not to have to sign in to quickbooks in order for it to send invoices or any other operation on quickbooks. I want to be able to write the functionality the application is allow to perform on the QuickbooksAPI by automatically signing in into quickbooks. How can I achieve this?
To word this differently, I want the NodeJS server to log in into quickbooks automatically if application user has the roles or permission to do a quickbooks action, such as creating and invoice or retrieve information. The application should grant itself permission to the OAuth2.0. How do I do this? with a JWT token? Not sure
A bit of background: I was able to accomplish Oauth2.0 authentication by using node-quickbooks by mcohen module.
Thank you in advance
The application should grant itself permission to the OAuth2.0. How do I do this?
You can't.
But you may also be misunderstanding how OAuth is supposed to work.
You need to have the user go through the OAuth process ONCE. EXACTLY once. Never more than once.
Once you have them go through that process once, you get back an access token and a refresh token.
You can then use those tokens to get updated tokens whenever you want (e.g. refresh your access/refresh token programatically, without any user interaction at all). See the docs:
https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/oauth-2.0#refresh-the-token
So, have the user go through OAuth once. Then store the tokens in your app. Refresh the tokens via the refresh token API. The user just has to auth exactly once, and then everything else you can do automatically forever going forward.

Saving access tokens (Identityserver4)

I am using IdentityServer4 with a custom user store (based on SQL Server DB).
I want to know how can I store access tokens in order to check that every request have the right access token.
I tried to use the default operational store but it just saves the refresh tokens and authorization code.
Thanks in advance.
If I understand you correctly, you want to save access token on the server side so that you can authenticate user request. You do NOT need to store the access token on server side as IdentityServer has done this for you. If you set up your api (resource server) correctly with identity server, all you need is add [Authorize] on your api controllers (seems like that you're using .net core web api). You can find many examples on the IdentityServer docs and sample project on Github.
In the meantime, you may need to store the access token on client side because until a token expires there is no need to authenticate the user again; this depends on which grant type you use. This is particularly true when you use ResourceOwnerPassword grant; if you client side is a SPA (e.g. Angular) then normally access token is store in the browser's local storage; for each client request, you check whether there is already a token and if so also check it hasn't expired.
And it's possible to support refresh token for different grants so that user is auto re-authenticated when its access token expires.

Microsoft Graph API: how to get access token without browser

I would like to upload a given file to Sharepoint. I'm using the Microsoft Graph API.
The documentation follows this workflow:
1. If no token, redirect the user to the Microsoft signin page.
2. The user is then redirected to the application, with an access token
3. Use access token to have an authorization bearer
4. Do what you gotta do...
My problem is the sign-in part. I don't want my users to be redirected to the Microsoft signin page. I want my application to connect and get the access token in the background (with cURL or whatever).
How can I do that? Why is the "open in browser" necessary?
I tried to replicate the sign-in process, but all I get back is the HTML response from the signin page.
Thanks in advance.
Your application act as a single-tenant service or daemon app.
The documentation about this scenario is here : https://developer.microsoft.com/en-us/graph/docs/authorization/app_only
The application must be registered in the AzureAD directory corresponding to the Office365 tenant
A first request is made by passing the application unique identifier and secret key as registered in the directory. This request returns an access token
The access token can now be used in the Authorization header of the following request to the Microsoft Graph API.
This method (of using Client ID and Secret) works well but there are other ways which may be better suited for similar scenarios.
The one major thing which is missing in access token generated this way is a user, meaning the token only contains the identity of the OAuth application (client) which called it but is not associated with any user for the request.
This could have a couple of implications:
Since the token is not associated with a specific user you will not know who performed the operation. In your example, you would not know who uploaded the file (and other similar information may be missing).
Access token without users will not work at all for some methods. For those, you need a delegated token.
Creating a delegated token requires some effort, if you are interested you can find the details in my article:
Getting Access Token for Microsoft Graph Using OAuth REST API

AcquireToken() from Background Job

I am using Azure Active Directory and ADAL to interact with Exchange EWS of Office 365 with OAuth.
I know you can use authContext.AcquireToken() and It will manage all oauth for you. It will save, use, and refresh, tokens for you and also prompt to the user credentials when is required. The issue in my case is that I need the interaction in an Azure background web job so It wont be able to ask for the user credentials.
What I tried was getting the authorization code making the user visit the url from GetAuthorizationRequestURL(). Then getting a Token using AcquireTokenByAuthorizationCode() and saving the Refresh Token in the database. So when the background Job needs to connect to EWS it can use the Refresh Token (saved in the Db) using AcquireTokenByRefreshToken().
This approach works but I dont know how you can get a new Refresh Token when it expires after 14 days.
Any idea of how can I renew the refresh token or a better approach for using ADAL in a Background Job?
Thanks and regards!!
Here there's an idea. Create a simple console or win form app that requests your token. In that app, use a custom cache that saves tokens in a portable store (like an encrypted file, see https://github.com/AzureADSamples/NativeClient-DotNet). Run the app once to seed the cache. Then take that cache and deploy it together with your web job. Now for 90 days or so you'll be fine.
Another alternative is to use username/password flows but that's rarely a good idea and it entails many important limitations.

Resources