Closed devdeer-stephan closed 5 years ago
@devdeer-stephan
@jmprieur Thank you, this helped and I feel just a little stupid for not noticing that myself.
Now, if I call var accounts = await clientApplication.GetAccountsAsync()
the accounts are always empty, so I cannot use the accounts for a subsequent var token = await clientApplication.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync()
Am I missing some scope(s)?
no worries, @devdeer-stephan ;) Which token cache implementation are you using? I recommend you look at the sample I mentioned; this line is important https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapp/blob/0275b6e2f745ad9fda2958fc5461248702cf41b6/WebApp-OpenIDConnect-DotNet/OpenIdConnectOptionsSetup.cs#L115
Finally even if the following article is not especially for B2C, the principles remain the same: Web app that calls web APIs - code configuration
You might want to read the article: Scenario: Web app that calls web APIs
@jmprieur We had some issues with re-deployments where the user's cookie and the deleted in-memory-chache (from the re-deoployment) differed, so we chose to go for a redis cache:
// Get the token cache from redis, if the internal in-memory cache is not yet populated
clientApplication.UserTokenCache.SetBeforeAccess(
tokenArgs =>
{
var msalCacheContent = tokenArgs.TokenCache.SerializeMsalV3();
if (msalCacheContent != null)
{
// no action required if in-memory cache is already existent
return;
}
// get the cache content from redis
var redisCacheContent = _redisUserCache.Read(tokenArgs.Account.Username);
if (redisCacheContent.HasValue)
{
// load the redis contents to the local in-memory cache
tokenArgs.TokenCache.DeserializeMsalV3(redisCacheContent);
}
});
// write every change in the internal token cache back to the redis token cache
clientApplication.UserTokenCache.SetAfterAccess(
tokenArgs =>
{
if (!tokenArgs.HasStateChanged)
{
// no action required if no change has occured
return;
}
// get the local in-memory cache content and write it to redis
var msalCacheContent = tokenArgs.TokenCache.SerializeMsalV3();
_redisUserCache.Write(tokenArgs.Account.Username, msalCacheContent);
});
@jmprieur I just realized that tokenArgs.Account.Username
resolves to Missing from the token response
so the cache won't be able to handle that in any meaningful way. I switched that to tokenArgs.Account.HomeAccountId.ObjectId
and the resulting keys in the redis cache look a lot better.
Still, the problem with the empty accounts persists and I assume that I simply don't get that information in the token from the B2C. Is there some setting in the B2C I need to activate?
@devdeer-stephan : yes tokenArgs.Account.HomeAccountId.ObjectId is a good key. Or otherwise tokenArgs.Account.Identifier which concatenates the tenant Id and the object id.
@devdeer-stephan : BTW thanks for sharing the code to serialize to a Redis token cc: @kalyankrishna1 @MarkZuber
Are you happy that your issue is solved? do you want to close this issue?
@jmprieur
I think I might still have some caching problem. It seems var msalCacheContent = tokenArgs.TokenCache.SerializeMsalV3();
will never result in null
, as even a freshly initialized cache already had 17 bytes of content. I might need to enforce deserializing the redis cache at least once initially.
I will report back shortly.
@devdeer-stephan any update? are we able to close this issue? thanks.
@devdeer-stephan : the right way to handle the cache is to subscribe to the serialization events. Please see this PR about what's right to do: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/pull/106
proposing to close this issue. Don't hesitate to reopen (or open a more explicit issue) if you disagree
Which Version of MSAL are you using ?
<PackageReference Include="Microsoft.Identity.Client" Version="3.0.8" />
Platform
What authentication flow has the issue?
Is this a new or existing app? The app is in production with MSAL 2.7.0, and I have upgraded to MSAL 3.0.8 on my dev-branch
Repro Inside my implementation of
IConfigureNamedOptions<OpenIdConnectOptions>
:Expected behavior When calling
clientApplication.AcquireTokenByAuthorizationCode
I want to receive a authentication token.Actual behavior Calling
clientApplication.AcquireTokenByAuthorizationCode
thows anMsalServiceException
with the message"AADSTS50049: Unknown or invalid instance.\r\nTrace ID: 9d5948e6-486f-4ea8-b28c-21af7b681b00\r\nCorrelation ID: 3be8e81f-9bc2-45c9-bbbd-062a71a99b57\r\nTimestamp: 2019-05-21 14:48:15Z"
Possible Solution From what I've researched so far this issue used to be resolved by disabling the authority validation. As far as I can see I did just that. Did I miss something?