question

RekellCaraan-3504 avatar image
0 Votes"
RekellCaraan-3504 asked ShwetaMathur commented

Browser is continously looping after signing in ADB2C

A web app built in .Net Core 3.1 calling a protected custom web API built in .Net Core 3.1 too. Both web app and web api is using the one registered app in ADB2C tenant. That registered app has scope and redirect URIs. Access token and ID token is enabled too. Sign-in user flow is created and configured for local identity and MS identity. Using the default UI page for sign-in but plans to customize it later. Both web api and web app is also using azure key vault for some confidential values.

The issue is that after signing in from the Sign-in page using either local identity or MS identity, the browser is just looping continuously. Sometimes the error is something like "the resource you are looking for has been removed or changed".

Below are my configurations and codes:

Azure App Settings and appsettings.json of Web App or client
"AzureAdB2C": {
"Scopes": "user_access",
"Instance": "https://{tenant}.b2clogin.com",
"ClientId": "{the registered app client ID}",
"Domain": "{tenant}.onmicrosoft.com",
"SignedOutCallbackPath": "/{signin policy}/oauth2/v2.0/logout/",
"SignUpSignInPolicyId": "{signin policy}",
"ClientSecret": "{the registered app client secret}"
},

Web App Startup >> ConfigureServices
services.AddDistributedMemoryCache();

         .....
         .....
         services.Configure<CookiePolicyOptions>(options =>
         {
             // This lambda determines whether user consent for non-essential cookies is needed for a given request.
             options.CheckConsentNeeded = context => true;
             options.MinimumSameSitePolicy = SameSiteMode.None;
             // Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
             options.HandleSameSiteCookieCompatibility();
         });

         services
             .AddMicrosoftIdentityWebAppAuthentication(Configuration, Constants.AzureAdB2C)
             .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "user_access" })
             //.EnableTokenAcquisitionToCallDownstreamApi()
             .AddInMemoryTokenCaches();

         services.AddAuthorization(options =>
         {
             var groups = new Groups(Configuration);
             options.AddPolicy("IsAdmin", policy =>
                 policy.RequireClaim(Groups.ClaimName, groups.Admin));
             options.AddPolicy("IsUser", policy =>
                 policy.RequireClaim(Groups.ClaimName, groups.User));

             options.AddPolicy("GeneralAccess", policy =>
                 policy.RequireClaim(Groups.ClaimName, groups.User, groups.Admin));
             options.FallbackPolicy = options.GetPolicy("GeneralAccess");
         });

         services.AddControllersWithViews()
                 .AddMicrosoftIdentityUI();

         services.AddRazorPages();

         //Deployment Mode
         var deploymentMode = Configuration.GetSection("DeploymentMode");
         services.Configure<DeploymentMode>(deploymentMode);
         //Set Session Timeout. Default is 20 minutes.
         services.AddSession(options =>
         {
             options.IdleTimeout = TimeSpan.FromMinutes(30);
         });
         //services.AddSession(options =>
         //{
         //    options.Cookie.HttpOnly = true;
         //    options.Cookie.IsEssential = true;
         //});
         services.AddMvc().AddSessionStateTempDataProvider();
         services.AddSession();
         services.AddMvc()
           .SetCompatibilityVersion(CompatibilityVersion.Latest);

         //Configuring appsettings section AzureAdB2C, into IOptions
         services.AddOptions();
         services.Configure<OpenIdConnectOptions>(Configuration.GetSection("AzureAdB2C"));

Web App Controller(s)
[Authorize]
//[Authorize(Policy = "GeneralAccess")]
//[RequiredScope(RequiredScopesConfigurationKey = "AzureAdB2C:Scopes")]
public class HomeController : Controller {
...
...
}

Web App Service for token acquisition
....
HttpResponseMessage response = null;
string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(requiredScopes);
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
....



azure-ad-b2c
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @RekellCaraan-3504,

Thanks for reaching out.

Could you please confirm the statement "Both web app and web api is using the one registered app in ADB2C tenant" .

I am assuming you should have two application registered in ADB2C tenant where one application(webApp) is calling another application(WebAPI). Please confirm my understanding to assist further on this.

Also, Could you share any reference document you are following for above setup.

Thanks,
Shweta

0 Votes 0 ·

Hi Shweta,

Yes, I am using one registered app in ADB2C tenant for both web app .netcore and web api. Even though I have used pair registration apps (one for web api and another one for web app), I would like to know/try if a single registered app can suffice for both.

I have referenced a couple of documents and MSDN YouTube tutorials but below are some of it:

https://github.com/AzureAD/microsoft-identity-web/wiki

https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/4-WebApp-your-API/4-2-B2C

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/azure-ad-b2c?view=aspnetcore-6.0

https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-call-api-acquire-token?view=aspnetcore-6.0&tabs=aspnetcore

https://docs.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-sample-web-app-with-api?tabs=visual-studio

https://docs.microsoft.com/en-us/samples/azure-samples/active-directory-b2c-dotnet-webapp-and-webapi/azure-ad-b2c-call-an-aspnet-web-api-from-an-aspnet-web-app/

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-6.0

https://docs.microsoft.com/en-us/azure/active-directory-b2c/authorization-code-flow

https://docs.microsoft.com/en-us/azure/active-directory-b2c/integrate-with-app-code-samples

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.azureadb2c.ui.azureadb2cdefaults?view=aspnetcore-6.0


Thank you for your support.

Best Regards,
Rekell

0 Votes 0 ·

1 Answer

ShwetaMathur avatar image
0 Votes"
ShwetaMathur answered ShwetaMathur commented

Hi @ RekellCaraan-3504,

Thanks for the update.

I have tried to replicate the issue by registering web app and web api and expose the scope of API in web app and able to call the web API successfully from web APP in .NET core.

I tried multiple combinations to reproduce the error at my end, but I am able to sign in the B2C application and calling web API successfully after providing credentials.
The error you are getting might be due to incorrect configurations in the application.

I am trying to understand the use case where web App is calling itself for webAPI. The scope of webAPI need to expose for which client applications can obtain access tokens and call webAPI from web app. In case of single registered application, webapp calling the application itself.

Are you also facing this issue when you are registering the two applications separately for both web application and web API?

The scope you are passing in configuration file does not seem to be correct. It should be redirected to API scope with its address. Below is the configuration file I am using for which i am able to call web API successfully.

{
"AzureAdB2C": {

 "Instance": "https://tenant.b2clogin.com",
 "ClientId": "xxxx-xxx-xx-xx-xx",
 "Domain": "tenant.onmicrosoft.com",
 "SignedOutCallbackPath": "/B2C_1_signupsignin//oauth2/v2.0/logout/",
 "SignUpSignInPolicyId": "B2C_1_signupsignin",
 "ClientSecret": "xxx"

},
"API": {

 "APIScope": "https://tenant.onmicrosoft.com/my-api/access_as_user",
 "APIBaseAddress": "https://localhost:44332"

},

In startup. cs

services.AddMicrosoftIdentityWebAppAuthentication(Configuration, Constants.AzureAdB2C)
.EnableTokenAcquisitionToCallDownstreamApi(new string[] { Configuration["API:APIScope"] })
.AddInMemoryTokenCaches();

I refer https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/4-WebApp-your-API/4-2-B2C to call webApp from webAPI.

Note: Posting it as answer as comment has limit restriction.

· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Shweta,

I am still figuring out any misconfigurations on the client application using the single-registered-app.
I'll respond once we are able to fix the problem on our side or if the issue still exists.
I'll also try to verify if the same issue exists using a non single-registered-app (or the pair registered app) and I'll let you know too.

Thank you.

-Rekell

1 Vote 1 ·

Hi Shweta,

You can close this ticket and/or mark this as resolved. The issue is more on configurations on the project. Thank you for your support and advice on this.

Regards,
Rekell

0 Votes 0 ·
ShwetaMathur avatar image ShwetaMathur RekellCaraan-3504 ·

@RekellCaraan-3504 ,

Thanks for the update. Glad you are able to resolve the issue.

Please do not forget to "Accept the answer" wherever the information provided helps you to help others in the community.

Thanks,
Shweta


0 Votes 0 ·