Comments (21)
@bgavrilMS any update would be appreciated. It's not to put any pressure jut wanted to know.
from active-directory-b2c-dotnet-webapp-and-webapi.
Having the same issue myself - code + deployment was working fine two months ago. I'm using a B2C standard sign in and sign up flow but the user is not authenticated after the sign up flow completes.
from active-directory-b2c-dotnet-webapp-and-webapi.
Logged exactly the same ticket with MSFT back in Jan. They were unable/unprepared to provide support for the sample code despite it being from Microsoft.
regards
from active-directory-b2c-dotnet-webapp-and-webapi.
@BrianS-CF thanks for sharing this with me. This is very strange that Microsoft team is not at all responding. I am sort of stuck with this issue. And there is no way, I can reach out to any of the team mates who worked on MSAL.NET library.
from active-directory-b2c-dotnet-webapp-and-webapi.
We will revamp this sample to use Microsoft.Identity.Web - our higher level API https://github.com/AzureAD/microsoft-identity-web/wiki/asp-net
If you use ASP.NET Core (all new projects should!), then I recommend looking at the official ASP.NET Core sample:
https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master
from active-directory-b2c-dotnet-webapp-and-webapi.
Hello bgavrilMS, we are not using .NET Core, our app is based on .NET (4.7.2 && MVC 3). We are struggling to know why we are getting account as null.
Any pointers for troubleshotting would be very helpful.
from active-directory-b2c-dotnet-webapp-and-webapi.
@spalmcc - when you log in the user the first time, you get an auth code and that gets exchanged for a token. This happens here:
Look at AuthenticationResult
property - it will have an Account object - note its id. This is when the auth artefacts get written to the cache (i.e. cache SET operation)
Next, look at the GetB2CMsalAccountIdentifier / GetAccountsCall. What account id does it compute. What is the value here? (this is the cache GET operation).
Note: I think I can alraedy spot a problem -
from active-directory-b2c-dotnet-webapp-and-webapi.
CC @jmprieur
from active-directory-b2c-dotnet-webapp-and-webapi.
@bgavrilMS
Please have a look to the following:-
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
{
try
{
/*
The MSALPerUserMemoryTokenCache
is created and hooked in the UserTokenCache
used by IConfidentialClientApplication
.
At this point, if you inspect ClaimsPrinciple.Current
you will notice that the Identity is still unauthenticated and it has no claims,
but MSALPerUserMemoryTokenCache
needs the claims to work properly. Because of this sync problem, we are using the constructor that
receives ClaimsPrincipal
as argument and we are getting the claims from the object AuthorizationCodeReceivedNotification context
.
This object contains the property AuthenticationTicket.Identity
, which is a ClaimsIdentity
, created from the token received from
Azure AD and has a full set of claims.
*/
IConfidentialClientApplication confidentialClient = MsalAppBuilder.BuildConfidentialClientApplication(new ClaimsPrincipal(notification.AuthenticationTicket.Identity));
// Upon successful sign in, get & cache a token using MSAL
AuthenticationResult result = await confidentialClient.AcquireTokenByAuthorizationCode(Globals.Scopes, notification.Code).ExecuteAsync();
// Azure
DisplayUserInfo(result);
}
catch (Exception ex)
{
throw new HttpResponseException(new HttpResponseMessage
{
StatusCode = HttpStatusCode.BadRequest,
ReasonPhrase = $"Unable to get authorization code {ex.Message}."
});
}
}
private void DisplayUserInfo(AuthenticationResult authResult)
{
if (authResult != null)
{
var token = new JwtSecurityToken(jwtEncodedString: authResult.IdToken);
// string expiry = token.Claims.First(c => c.Type == "expiry").Value;
string userName = token.Claims.First(c => c.Type == "extension_userName").Value;
string customRoles = token.Claims.First(c => c.Type == "extension_CustomRole").Value;
}
}
From sample code we know about we can access the id token. access token / claims. But that's not the issue.
We cant to call a end point using WepAPI for that we need to have access to the Access Token in the controller.
Refer the following from sample code:-
public async Task Index()
{
try
{
// Retrieve the token with the specified scopes
AuthenticationResult result = await AcquireTokenForScopes(new string[] { Globals.WriteTasksScope }); [This call is failing]
private async Task AcquireTokenForScopes(string[] scopes)
{
IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var account = await cca.GetAccountAsync(ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier());
return await cca.AcquireTokenSilent(scopes, account).ExecuteAsync();
}
var account is coming as null.
My configuration of web api on Azure under appservice seems to be correct as I could access the end points by using postman (configured the postman and I can get access token)
Following is what you posted in previous post which is not clear to me at all
Next, look at the GetB2CMsalAccountIdentifier / GetAccountsCall. What account id does it compute. What is the value here? (this is the cache GET operation).
Note: I think I can alraedy spot a problem -
Could you please be little more explicit here?
from active-directory-b2c-dotnet-webapp-and-webapi.
You had mentioned the following"-
Next, look at the GetB2CMsalAccountIdentifier / GetAccountsCall. What account id does it compute. What is the value here? (this is the cache GET operation).
And this is what "return $"{userObjectId}-{Globals.SignUpSignInPolicyId}.{tenantId}";" being returned.
Hope this would help.
from active-directory-b2c-dotnet-webapp-and-webapi.
Hi @spalmcc - I have a PR out with a possible fix. Please try it out.
MSALPerUserMemoryTokenCache
is an old cache implementation that we forgot to fully remove. There is no need for a ClaimsPrincipal when you create the ConfidentialClientAPplication object. You only need ClaimsPrincipal to know what the account id is.
from active-directory-b2c-dotnet-webapp-and-webapi.
@bgavrilMS
thanks alot. I will try and revert back.
from active-directory-b2c-dotnet-webapp-and-webapi.
I tried and I am getting account as null in task controller.
private async Task<AuthenticationResult> AcquireTokenForScopes(string[] scopes)
{
IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var account = await cca.GetAccountAsync(ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier()); // null
return await cca.AcquireTokenSilent(scopes, account).ExecuteAsync();
}
from active-directory-b2c-dotnet-webapp-and-webapi.
@bgavrilMS
one more observation from Account controller, I tested the signout and I am getting account value as null , please check the comment in the following code. This might help you in some way.
public async Task SignOut()
{
// To sign out the user, you should issue an OpenIDConnect sign out request.
if (Request.IsAuthenticated)
{
// await MsalAppBuilder.ClearUserTokenCache();
// Remove all tokens from MSAL's cache
var clientApp = MsalAppBuilder.BuildConfidentialClientApplication();
string accountId = ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier();
IAccount account = await clientApp.GetAccountAsync(accountId); // account is null
await clientApp.RemoveAsync(account);
// Then sign-out from OWIN
IEnumerable<AuthenticationDescription> authTypes = HttpContext.GetOwinContext().Authentication.GetAuthenticationTypes();
HttpContext.GetOwinContext().Authentication.SignOut(authTypes.Select(t => t.AuthenticationType).ToArray());
Request.GetOwinContext().Authentication.GetAuthenticationTypes();
}
}
from active-directory-b2c-dotnet-webapp-and-webapi.
What is the value of ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier()
and what is the value of AuthenticationResult.Account.AccountId
? These 2 must match for the cache to be hit.
The accountID is made up of:
- tenant_id
- object_id
- policy name
In many cases the tenant_id
is not present in the ID token (i.e. ClaimsPrincipal) - claim tid
. See the first known issue here which will tell you how to configure your app to add the claim.
from active-directory-b2c-dotnet-webapp-and-webapi.
the format for ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier() is as follows:-
"userObjectId-SignUpSignInPolicyId.tenantId"
property "AuthenticationResult.Account.AccountId" is not there instead I found the "AuthenticationResult.Account.HomeAccountId" and the value is as follows:-
"{AccountId: <userObjectId>-<SignUpSignInPolicyId>.<tenant>}"
Also for your ease refer the following 3 screen shots:-
Also I checked the ID Token and I do not see tenant id in that token. I will check how the same can be configured.
from active-directory-b2c-dotnet-webapp-and-webapi.
@bgavrilMS I am stuck with something at work so not able to further look into this. I will revert back in some time.
from active-directory-b2c-dotnet-webapp-and-webapi.
im seeing the same exception flying by using the example from Microsoft
from active-directory-b2c-dotnet-webapp-and-webapi.
I'm also facing the same issue. Do we have any solution for that.
from active-directory-b2c-dotnet-webapp-and-webapi.
Folks, we now have a sample up and running for ASP.NET + Microsoft.Identity.Web. This library provides higher level APIs and integration with both ASP.ENT and ASP.NET Core.
We don't have the B2C variant, but it should be fairly similar. Please see
https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect
from active-directory-b2c-dotnet-webapp-and-webapi.
Note to all - there seems to have been a bug for my issue that was resolved by bumping packages. I was using Blazor Server for my client UI, connecting to a .NET API. Here is what I've updated to:
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.12" NoWarn="NU1605" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.12" NoWarn="NU1605" />
from active-directory-b2c-dotnet-webapp-and-webapi.
Related Issues (20)
- make the sample code work behind organization proxy HOT 2
- App very old - Do you have once that works? HOT 7
- Cannot create SSL/TLS link when retrieving metadata HOT 9
- No account or login hint was passed to the AcquireTokenSilent call HOT 12
- Could not load file or assembly Microsoft.Identity.Client, Version=4.37.0.0 HOT 1
- Sign up / Sign in failed HOT 4
- Upgrade to .NET 6 for macOS HOT 3
- Why we need `ReaderWriterLockSlim` in OpenIdConnectCachingSecurityTokenProvider?
- Metadata Endpoint Url cannot be accessed from the sample code
- Bad Request open two tabs with the same web HOT 1
- HttpContext.GetOwinContext().Get<string>("Policy") is a global setting, not a per user session setting HOT 1
- How to use MSAL in this example to do refresh token from azure ad b2c?
- Instructions for configuration back end (.NET web API Project) on AppService is not clear as per the documentation
- How to access "ID token"/"claims" in Web Controllers? HOT 5
- Startup Error IDX20807: Unable to retrieve document from: 'System.String' / TLS 1.2 HOT 2
- Implicit grant
- Nuget package Owin.1.0.1 can not be found HOT 1
- Redirect results in 404.
- The demo project is out of date for decade, can we have the latest .NET 8 version? HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from active-directory-b2c-dotnet-webapp-and-webapi.