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;
}
}