Coder Social home page Coder Social logo

Comments (12)

jmprieur avatar jmprieur commented on September 26, 2024 1

@aremo-ms : you might want to also replace

MSALPerUserMemoryTokenCache userTokenCache = new MSALPerUserMemoryTokenCache(clientapp.UserTokenCache, currentUser ?? ClaimsPrincipal.Current);

by something like in the AAD sample:

https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect/blob/69f656e139fb033ca3a6d9815a888a15677f5c96/WebApp/Utils/MsalAppBuilder.cs#L46

from active-directory-b2c-dotnet-webapp-and-webapi.

aremo-ms avatar aremo-ms commented on September 26, 2024 1

@aremo-ms Thanks for your time. We could arrange a Team meeting one on one monday Nov 8 around 9h30 or 10h00 AM. Since you appear to be in Ottawa, we won't have any problem with the timezones.

This way I can show you all my actual setup (users and policies in B2C, code, etc.)

Sounds good. Looking forward to chat

from active-directory-b2c-dotnet-webapp-and-webapi.

aremo-ms avatar aremo-ms commented on September 26, 2024 1

@aremo-ms I just found out the problem! The IConfidentialClient GetAccountAsync method is case sensitive. My custom policy name is in capital letters.

So basicaly to be sure to be 100% idiot proof, I would suggest you just modify your TaskWebApp.Controllers.TasksController.AcquireTokenForScopes() method and add a "ToLower()" call like this

 private async Task<AuthenticationResult> AcquireTokenForScopes(string[] scopes)
  {
      IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
      var account = await cca.GetAccountAsync(ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier().ToLower());
      return await cca.AcquireTokenSilent(scopes, account).ExecuteAsync();
  }

In anyway, I'll just close this issue as it seems to work (except for the original bug because I still have to add the ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; line in the startup, but that must be a particularity of our environments).

Thanks for your help, both you and @jmprieur

@cotepatrice Thanks for your update, I will look into this today. My other question is about TLS... I will need to read a little bit more and will update you as well.

from active-directory-b2c-dotnet-webapp-and-webapi.

aremo-ms avatar aremo-ms commented on September 26, 2024 1

I was having this issue too. However adding .ToLower() like suggested didn't fix it.

Specifically the issue was GetAccountAsync in TaskController.cs/AcquireTokenForScopes would always return null. Even calls to GetAccountsAsync() while trying to just debug would return 0 items. Yet, I was still able to login and get claims. It was only when trying to access the 'todos' page that I'd have issues. Likely due to how the cache was storing my tokens and the key being not exactly the same?

What did fix things, was changing all the constants defined in both web.configs to be lower case. Even though the actual policy names were capitalized. I suggest add a nice bold comment somewhere (hopefully its not there and I missed it) in the docs that says you need to use all lower case names for profiles.

My profile names were in the style of B2C_1_Demo_susi and my web.config matched that exactly. It was until I changed my web.config values to be all lower case did things work.

Hope this helps someone else.

Hi @mattd-its
Thank you for your update, I will check.

Alex

from active-directory-b2c-dotnet-webapp-and-webapi.

cotepatrice avatar cotepatrice commented on September 26, 2024

I've seen that the code keeps calling the MsalAppBuilder.BuildConfidentialClientApplication that basically is a factory that creates a new client every time. That's probably why the cache is always empty? Because it's a new one every single time?

from active-directory-b2c-dotnet-webapp-and-webapi.

cotepatrice avatar cotepatrice commented on September 26, 2024

@aremo-ms I can confirm that the problem is with the GetAccountAsync(string identifier) function. So probably with the underlying cache management. I made a simple change using GetAccountsAsync() (even if deprecated, just for testing) instead of the the other and I get the account. Then everything seems to work.

In TaskWebApp.Controllers.TaskControllers

// var account = await cca.GetAccountAsync(ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier());
var allAccounts = await cca.GetAccountsAsync();
var account = allAccounts.FirstOrDefault();

But I, will wait for your modifications using the serialized cache before trying to integrate this inside our own solution.

NOTE that in the account I get, I see there's no username. But I see the "name" claim in the Claims view. This is the information in the "account" variable:

TenantProfiles: null
Username: "Missing from the token response environment"
Environment: my-tenant .b2clogin.com
HomeAccountId: my-user-object-id-my-userflow-name.my-tenant-id

from active-directory-b2c-dotnet-webapp-and-webapi.

aremo-ms avatar aremo-ms commented on September 26, 2024

@aremo-ms I can confirm that the problem is with the GetAccountAsync(string identifier) function. So probably with the underlying cache management. I made a simple change using GetAccountsAsync() (even if deprecated, just for testing) instead of the the other and I get the account. Then everything seems to work.

In TaskWebApp.Controllers.TaskControllers

// var account = await cca.GetAccountAsync(ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier());
var allAccounts = await cca.GetAccountsAsync();
var account = allAccounts.FirstOrDefault();

But I, will wait for your modifications using the serialized cache before trying to integrate this inside our own solution.

NOTE that in the account I get, I see there's no username. But I see the "name" claim in the Claims view. This is the information in the "account" variable:

TenantProfiles: null Username: "Missing from the token response environment" Environment: my-tenant .b2clogin.com HomeAccountId: my-user-object-id-my-userflow-name.my-tenant-id

@cotepatrice
I've merged my PR into master, please confirm it work now. Feel free to close the issue then.

from active-directory-b2c-dotnet-webapp-and-webapi.

cotepatrice avatar cotepatrice commented on September 26, 2024

@aremo-ms I still have the exact same problem. In TaskWebApp.Controllers.TasksController, line 173, the "GetAccountAsync" method always returns null (but the key returned by the "GetB2CMsalAccountIdentifier" method seems to be OK). Tried a couple of times, with a logout first, no success.

from active-directory-b2c-dotnet-webapp-and-webapi.

aremo-ms avatar aremo-ms commented on September 26, 2024

@aremo-ms I still have the exact same problem. In TaskWebApp.Controllers.TasksController, line 173, the "GetAccountAsync" method always returns null (but the key returned by the "GetB2CMsalAccountIdentifier" method seems to be OK). Tried a couple of times, with a logout first, no success.

@cotepatrice I'm sorry this is still not resolved for you. I will need to be able to reproduce it on my local environment. Currently I cannot. Could you please provide me more details about your user so I will try to create same one on my side. Alternatively, you can connect with me through Teams and will be happy to chat with you. My work e-mail address is [email protected]

from active-directory-b2c-dotnet-webapp-and-webapi.

cotepatrice avatar cotepatrice commented on September 26, 2024

@aremo-ms Thanks for your time. We could arrange a Team meeting one on one monday Nov 8 around 9h30 or 10h00 AM. Since you appear to be in Ottawa, we won't have any problem with the timezones.

This way I can show you all my actual setup (users and policies in B2C, code, etc.)

from active-directory-b2c-dotnet-webapp-and-webapi.

cotepatrice avatar cotepatrice commented on September 26, 2024

@aremo-ms I just found out the problem! The IConfidentialClient GetAccountAsync method is case sensitive. My custom policy name is in capital letters.

So basicaly to be sure to be 100% idiot proof, I would suggest you just modify your TaskWebApp.Controllers.TasksController.AcquireTokenForScopes() method and add a "ToLower()" call like this

 private async Task<AuthenticationResult> AcquireTokenForScopes(string[] scopes)
  {
      IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
      var account = await cca.GetAccountAsync(ClaimsPrincipal.Current.GetB2CMsalAccountIdentifier().ToLower());
      return await cca.AcquireTokenSilent(scopes, account).ExecuteAsync();
  }

In anyway, I'll just close this issue as it seems to work (except for the original bug because I still have to add the ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; line in the startup, but that must be a particularity of our environments).

Thanks for your help, both you and @jmprieur

from active-directory-b2c-dotnet-webapp-and-webapi.

mattd-its avatar mattd-its commented on September 26, 2024

I was having this issue too. However adding .ToLower() like suggested didn't fix it.

Specifically the issue was GetAccountAsync in TaskController.cs/AcquireTokenForScopes would always return null. Even calls to GetAccountsAsync() while trying to just debug would return 0 items. Yet, I was still able to login and get claims. It was only when trying to access the 'todos' page that I'd have issues. Likely due to how the cache was storing my tokens and the key being not exactly the same?

What did fix things, was changing all the constants defined in both web.configs to be lower case. Even though the actual policy names were capitalized. I suggest add a nice bold comment somewhere (hopefully its not there and I missed it) in the docs that says you need to use all lower case names for profiles.

My profile names were in the style of B2C_1_Demo_susi and my web.config matched that exactly. It wasn't until I changed my web.config values to be all lower case did things work.

Hope this helps someone else.

from active-directory-b2c-dotnet-webapp-and-webapi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.