SolvedIdentityServer4 Cannot authenticate using the IdentityServer4 ver. 2.0

Here's how I changed my Startup.cs file when I upgraded to IdentityServer4 ver. 2.0 in my ASP.NET Core 2.0 project (uses .NET Framework 4.7).

OLD:

public void ConfigureServices(IServiceCollection services)
{
  services.AddLogging();
  services.AddSingleton(Configuration);

  services
    .AddScoped<IDbContextFactory<AppDbContext>, AppDbContextFactory>()
    .AddScoped(sp => sp.GetService<IDbContextFactory<AppDbContext>>().Create())
    .AddScoped<IUserClaimsPrincipalFactory<User>, AppUserClaimsPrincipalFactory>()
    .AddScoped<AppUserStore>()
    .AddScoped<AppRoleStore>()
    .AddScoped<AppUserManager>();

  services.AddIdentity<User, Role>()
    .AddUserStore<AppUserStore>()
    .AddRoleStore<AppRoleStore>()
    .AddUserManager<AppUserManager>()
    .AddClaimsPrincipalFactory<AppUserClaimsPrincipalFactory>();

  services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
    .AddInMemoryApiResources(IdentityConfig.GetApiResources())
    .AddInMemoryClients(IdentityConfig.GetClients())
    .AddAspNetIdentity<User>();   

  services.AddMvc()
}     

public void Configure(IApplicationBuilder app, ...)
{
  ...

  app.UseIdentity()
     .UseIdentityServer()
     .UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
     {
       Authority = Constants.AppUrl,
       ApiName = Constants.ApiScope,
       ApiSecret = Constants.XamarinClientSecret,
       EnableCaching = true,
       AutomaticAuthenticate = true,
       RequireHttpsMetadata = false,
     });

  app.UseMvc();
}

New:

public void ConfigureServices(IServiceCollection services)
{
  services.AddLogging();
  services.AddSingleton(Configuration);

  services
    .AddScoped<IDbContextFactory<AppDbContext>, AppDbContextFactory>()
    .AddScoped(sp => sp.GetService<IDbContextFactory<AppDbContext>>().Create())
    .AddScoped<IUserClaimsPrincipalFactory<User>, AppUserClaimsPrincipalFactory>()
    .AddScoped<AppUserStore>()
    .AddScoped<AppRoleStore>()
    .AddScoped<AppUserManager>();

  services.AddIdentity<User, Role>()
    .AddUserStore<AppUserStore>()
    .AddRoleStore<AppRoleStore>()
    .AddUserManager<AppUserManager>()
    .AddClaimsPrincipalFactory<AppUserClaimsPrincipalFactory>();

  services.AddIdentityServer(options=> {           
  })
    .AddDeveloperSigningCredential()
    .AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
    .AddInMemoryApiResources(IdentityConfig.GetApiResources())
    .AddInMemoryClients(IdentityConfig.GetClients())
    .AddAspNetIdentity<User>()
    .AddJwtBearerClientAuthentication();


  services.AddMvc()
    .AddJsonOptions(o =>
    {
      var settings = JsonSerializerSettingsProvider.CreateSerializerSettings();
      var hSettings = new MyAppSerializerSettings();
      hSettings.DeepCopy(o.SerializerSettings);
    });

  services.AddAuthentication(o =>
    {
      o.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;          
    })
    .AddIdentityServerAuthentication(o =>
    {
      o.Authority = Constants.AppUrl;
      o.ApiName = Constants.ApiScope;
      o.ApiSecret = Constants.XamarinClientSecret;
      o.EnableCaching = true;
      o.RequireHttpsMetadata = false;
      o.SupportedTokens = SupportedTokens.Both;
    });      
}

public void Configure(IApplicationBuilder app, ...)
{
  ...

  app        
    .UseAuthentication()        
    .UseIdentityServer();         

  app.UseMvc();
}

MyProject.csproj changes:

Old:

<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.1" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="1.0.1" />
<PackageReference Include="IdentityServer4" Version="1.5.2" />

New:

<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.0.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.0.0" />
<PackageReference Include="IdentityServer4" Version="2.0.0" />

Looks like the sign-in works properly, as I'm able to get the claims and the token in the client side, but when I try to access protected resources (i.e. controllers decorated with Authorize), I get a 404 NotFound error.
This is what I see in the server-side console when trying to access the protected resource:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:52493/api/Lists/All
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: (null).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
      Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12]
      AuthenticationScheme: Identity.Application was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action MyProject.Controllers.ListsController.Get (MyProject.Api) in 65.0737ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 240.0852ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:52493/account/login?returnUrl=%2Fapi%2FLists%2FAll
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 0.8721ms 404

One line before the bottom line I can see this link:
http://localhost:52493/account/login?returnUrl=%2Fapi%2FLists%2FAll, but I'm wondering why is there such a link anyway, I'm using bearer authorization. There shouldn't be any redirects at all.
That's how it used to work so far and it broke.

What am I missing?

17 Answers

✔️Accepted Answer

That worked!
But instead of changing it in the controller, I added the following to the Startup.cs file, from:

    services.AddAuthentication(o =>
    {
      o.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
 +    o.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
    })

Other Answers:

What if you annotate the authorize with the scheme?

    [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]

More Issues: