I'm developing a little WPF-App that is supposed to query some data from the MS Graph API. I want to use SSO, so the user doesn't have to login to the app seperatly.
The app is run on a Azure AD joined device. The user is an AADC synchronized AD user. The AAD tenant is federated with ADFS. The user authenticates with Hello for Business (PIN) or via Password. The resulting problem is the same.
I can confirm that the user got a PRT via:
dsregcmd /status
AzureAdPrt: YES
In case it matters: The app registration in Azure AD is set to "Treat application as public client". And the following redirect URIs are configured:
- https://login.microsoftonline.com/common/oauth2/nativeclient
- https://login.live.com/oauth20_desktop.srf
- msalxxxxxxx(appId)://auth
- urn:ietf:wg:oauth:2.0:oob
Based on the examples I found, I'm using the following code to try to get an access token. However the GetAccountsAsync()
method doesn't return any users nor does it throw any error or exception.
Can anyone tell me, what I'm missing here?
Any help would be much appreciated!
PS: When I try this using "Interactive Authentication" it works fine.
public GraphAuthProvider(string appId, string tenantId, string[] scopes)
{
_scopes = scopes;
try
{
_msalClient = PublicClientApplicationBuilder
.Create(appId)
.WithAuthority(AadAuthorityAudience.AzureAdMyOrg, true)
.WithTenantId(tenantId)
.Build();
}
catch (Exception exception)
{
_log.Error(exception.Message);
_log.Error(exception.StackTrace);
throw;
}
}
public async Task<string> GetAccessToken()
{
_log.Info("Starting 'GetAccessToken'...");
var accounts = await _msalClient.GetAccountsAsync();
_userAccount = accounts.FirstOrDefault();
// If there is no saved user account, the user must sign-in
if (_userAccount == null)
{
_log.Info("No cached accounts found. Trying integrated authentication...");
[...]
}
else
{
// If there is an account, call AcquireTokenSilent
// By doing this, MSAL will refresh the token automatically if
// it is expired. Otherwise it returns the cached token.
var userAccountJson = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(_userAccount));
_log.Info($"Found cached accounts. _userAccount is: {userAccountJson}");
var result = await _msalClient
.AcquireTokenSilent(_scopes, _userAccount)
.ExecuteAsync();
return result.AccessToken;
}
}