I have an ASP.NET Core MVC application that uses Azure AD to authenticate users and allows users to upload and access documents in a shared onedrive folder. I currently have the permissions for this application set to delegated permissions and use access token cached on the backend to use these permissions and make MS Graph calls.
However, I may be moving away from Azure AD towards Okta so I am planning to switch to application permissions and the backend will just be the user saving to the shared folder and such.
However, I am just curious is there any forseen issues with a service account saving to a real users shared drive? Will the access token just be issued for the service account then rather then when the user logs in?
My current code for setting up azure authentication in program.cs is as follows:
var initialScopes = builder.Configuration.GetValue<string>
("DownstreamApi:Scopes")?.Split(' ');
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
builder.Configuration.Bind("AzureAd", options);
}).EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
I currently utilize MS Graph with these delegated tokens as follows in this example from my OneDrive service I created:
public class OneDrive : IOneDrive
{
private readonly GraphServiceClient _graphServiceClient;
private readonly ITokenAcquisition _tokenAcquisition;
private readonly string[] initialScopes;
private readonly MicrosoftIdentityConsentAndConditionalAccessHandler _consentHandler;
public OneDrive(GraphServiceClient graphServiceClient, ITokenAcquisition tokenAcquisition, IConfiguration configuration, MicrosoftIdentityConsentAndConditionalAccessHandler consentHandler)
{
_graphServiceClient = graphServiceClient;
_tokenAcquisition = tokenAcquisition;
initialScopes = configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');
this._consentHandler = consentHandler;
}
public async Task<IDriveItemSearchCollectionPage> DriveItemSearchAsync(string DriveID, string SearchItem)
{
var tries = 0;
var maxRetries = 1;
IDriveItemSearchCollectionPage response = null;
while (tries <= maxRetries)
{
tries++;
try
{
var queryOptions = new List<QueryOption>()
{
new QueryOption("select", "name,id,webUrl")
};
response = await _graphServiceClient.Me.Drives[DriveID].Root
.Search(SearchItem)
.Request(queryOptions)
.GetAsync();
tries = maxRetries+1;
}
catch (ServiceException svcex) when (svcex.Message.Contains("Continuous access evaluation resulted in claims challenge"))
{
try
{
Console.WriteLine($"{svcex}");
string claimChallenge = WwwAuthenticateParameters.GetClaimChallengeFromResponseHeaders(svcex.ResponseHeaders);
_consentHandler.ChallengeUser(initialScopes, claimChallenge);
}
catch (Exception ex2)
{
_consentHandler.HandleException(ex2);
}
}
}
return response;
}
}