Browser is continously looping after signing in ADB2C

Rekell Caraan 21 Reputation points
2022-05-09T09:21:06.423+00:00

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://learn.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);
....

Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,922 questions
{count} votes

Accepted answer
  1. Shweta Mathur 29,856 Reputation points Microsoft Employee
    2022-05-11T17:22:09.23+00:00

    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.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.