Needs I need to be able to sync an online Excel spreadsheet with data from my database.
Question
Per the Microsoft Graph api docs, these writes require Delegated (work or school account)
permissions, and can not be done with Application permissions. However, I need to run this regularly on my server without user interaction. I have not yet found a way to obtain a token with the Delegated (work or school account)
permission type without user interaction. Is it possible to obtain the needed token/permissions on the server?
So far I have read a great many pages on Microsoft's authentication flows and application scenarios (e.g., this article and many downstream from it), but I have not been able to find a suitable path forward. From this research so far, the daemon application workflow seems most appropriate except that, so far as I can tell, it only allows Application permissions. The on-behalf-of flow seems like it might be an alternative, but 1. It seems odd that I should have to pick a Microsoft user to do this on behalf of, and 2. I'm not sure that I can authenticate a user once separate from the server process and then hang onto a token on the server (continuously refreshing it?). Is there a way to make that work? Is there a better way?
CodePudding user response:
If the API in the document you mentioned in your question it your target API, then it's obviously that you can only use delegated api permission. In other words, you have to make a user to sign in first, and you can only modify the excel file which is in the drive item belonging to the signed in user (I sign in with my account and I can modify my excel file, but I can't modify your excel file).
Therefore, you don't want to have a user to sign in each time, but you still want to use this API, you can only try to use ROPC flow to hard code the user name & password(e.g. excel admin account's username and password) in the application and only make your application to modify the excel files which belonging to this account.
var scopes = new[] { "Files.ReadWrite" };
var tenantId = "tenant_id";
var clientId = "azure_ad_app_id";
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var userName = "username";
var password = "password";
var userNamePasswordCredential = new UsernamePasswordCredential(
userName, password, tenantId, clientId, options);
var tokenRequestContext = new TokenRequestContext(scopes);
var request = await userNamePasswordCredential.GetTokenAsync(tokenRequestContext);
var res = request.Token;
CodePudding user response:
Note that: As mentioned in this MsDoc, to update the properties of range object, you have to grant delegated API permissions only.
- If you are granting Delegated API permissions then you have to Interactive authentication flows only (Auth-Code Flow, Implicit Flow)
- If you are granting Application API permissions then you have to use Client-Credential Flow.
I agree with @Tiny Wang, you can make use of ROPC Flow (but it is not recommended by Microsoft) where you can predefine username and password.
I generated the access token using below parameters:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
client_id:ClientID
client_secret:ClientSecret
username:[email protected]
password:****
grant_type:password
scope:https://graph.microsoft.com/Files.ReadWrite
By using the above access token, you can try updating the properties of range object like below:
Authenticate a user once separate from the server process and then hang onto a token on the server (continuously refreshing it?)
You can try increasing the lifetime of the access token if you don't want to refresh the access token continuously by referring this MsDoc.