I am writing a wpf application that uses Microsoft Graph Api to access and manage onedrive files. I am able to login as a user with previous access token that is stored in the cache but when there isn't any token in the cache I want to fetch the access token interactively so I'm using AcquireTokenInteractive but it doesn't open a login window.
I have tried the following things:
- Checking permission (My application have all the necessary permissions).
- Checking Redirect URI
This is the code
public class MSGraphHelper
{
private GraphServiceClient graphClient;
private static readonly string clientId = typeof(Credentials).GetField("OneDriveAppId").GetValue(null).ToString();
private static readonly string[] scopes = (string[])typeof(Credentials).GetField("OneDriveScopes").GetValue(null);
private static readonly string tenantId = "common";
private static readonly string redirectUri = "http://localhost";
private string accessToken;
private IPublicClientApplication msalClient;
// Constructors
public MSGraphHelper() { }
public MSGraphHelper(string userName)
{
Authenticate(userName);
}
private async Task Authenticate(string userName)
{
msalClient = PublicClientApplicationBuilder.Create(clientId).WithRedirectUri(redirectUri).Build();
TokenCacheHelper.EnableSerialization(msalClient.UserTokenCache, userName);
var accounts = await msalClient.GetAccountsAsync();
AuthenticationResult result;
try
{
result = await msalClient.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).WithTenantId(tenantId).ExecuteAsync();
accessToken = result.AccessToken;
}
catch (MsalUiRequiredException)
{
try
{
result = await msalClient.AcquireTokenInteractive(scopes).WithUseEmbeddedWebView(true).WithAuthority($"https://login.microsoftonline.com/{tenantId}").WithPrompt(Prompt.SelectAccount).ExecuteAsync();
accessToken = result.AccessToken;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
graphClient = new GraphServiceClient(new CustomAuthenticationProvider(accessToken));
}
}
// Inner class for authentication
private class CustomAuthenticationProvider : IAuthenticationProvider
{
private string accessToken;
public CustomAuthenticationProvider(string accessToken)
{
this.accessToken = accessToken;
}
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
}
public Task AuthenticateRequestAsync(RequestInformation request, Dictionary<string, object>? additionalAuthenticationContext = null, CancellationToken cancellationToken = default)
{
request.Headers.Add("Authorization", $"Bearer {accessToken}");
return Task.CompletedTask;
}
}
// Method to get the graphClient
public GraphServiceClient GetGraphClient()
{
return graphClient;
}
}