0
votes

I have a handful of client applications and an identity server application. Each application needs to have a a single-sign-on flow to it. So far I have been able to register my other applications without any problem. However, I have run into an infinite loop problem for my identity application. My thoughts are that somehow the AddIdentity() portion of my identity application is interfering with the IdentityServer4 client registration in the AddAuthentication() method call.

The problem application's sole responsibility is to manage the users that belong to all the applications but not to actually log them in(login is done using IdentityServer4). Here are the configurations.

// Config.cs  - problem client configuration
new Client
{

    ClientId = "identity",
    ClientName = "Identity Management",
    AllowedGrantTypes = GrantTypes.Implicit,
    RedirectUris = { "http://localhost:59990/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:59990/signout-callback-oidc" },
    AllowedScopes = GetAllowedScopes(),
},

I don't really think there is anything wrong config.cs since all my applications prior to this one are able to sign in using the same client registration code.

// ConfigureServices.cs - for client that has redirect loop 
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<SafetyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SafetyPlusConnection")));


services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

services.AddIdentity<SafetyUser, SafetyRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddRoleManager<RoleManager<SafetyRole>>()
    .AddDefaultUI(UIFramework.Bootstrap4)
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;
        options.ClientId = "identity";
        options.SaveTokens = true;
    });

services.AddScoped<RoleService>();

The remaining configuration is is just some boilerplate code.

// Configure.cs - in the problem application
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();

// Register.cs - code for registering new users (needs authorization first)
[Authorize]
public class RegisterModel : PageModel

When I navigate to my register page which is decorated with the [Authorize] attribute I am properly logged into IdentityServer and asked for access to my openid and profile privileges. When, I accept the request the application starts an infinite loop.

These following three requests are repeated in an infinite loop.

http://localhost:59990/signin-oidc

enter image description here

http://localhost:59990/Identity/Account/Register enter image description here

http://localhost:5000/connect/authorize?client_id=identity&redirect_uri=http%3A%2F%2Flocalhost%3A59990%2Fsignin-oidc&response_type=id_token&scope=openid%20profile&response_mode=form_post&nonce=...(elided encoded text) enter image description here

1

1 Answers

1
votes

When you call AddIdentity<>, you already setup authentication with multiple options. So try to override all the three defaults:

services.AddAuthentication(sharedOptions =>
{
  sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
  sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
  sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})

as described in the sample