Search code examples
c#asp.net-coreidentityserver4asp.net-core-identityasp.net-core-mvc-2.1

IdentityServer4 Asp.Net Core Identity


I'm trying to create basic IdentityServer4 with Asp.Net Core Identity, as in this tutorial.

But when I call the login method:

return Challenge(new AuthenticationProperties { RedirectUri = "/Home/Index" }, "oidc");

I get a 404 error:

http://localhost:5000/account/login?returnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dmvc%26redirect_uri%3Dhttps%253A%252F%252Flocalhost%253A44391%252Fsignin-oidc%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520api1%26response_mode%3Dform_post%26nonce%3D636682993147514721.ZDA2MmI5ZTgtMWU3Yi00ZjMzLTkyODMtZjBiNWIzMjUzZTRjZmYxMjIxYWItOTk5NS00OGJlLWE0M2EtOTg3ZTYyM2EzZWVk%26state%3DCfDJ8D1ISazXjTpLmRDTOwhIeT5cVwo-oh7P4hDeZa0Q7cSfU6vKRDTEu3RHraTyz4Wb8oQngGo-qAkzinXV2yFJuqClVRB_1gwLLXIvVK4moxtgGjZUGUJIDmoqQHrQCOxGNJLrGkaBiS74vxd1el8N1wSseoSBlqZD94OlShI53wgPNKXPiDzT0FLOI47MNwHwzW0d5q0n752kZiVp2V31CZemI6wtaEgte3Mb9iouFzrSyAW5XaBMdDEnAGPCNZ2d5Zfgwb2Cmp61B-I9t05aDHqR-5cxYtr0PVVM6PwBKy-1olSFH8uIc8ku0UJn7PY0WA%26x-client-SKU%3DID_NETSTANDARD1_4%26x-client-ver%3D5.2.0.0

Do I need any additional Views and Controllers? I thought that what is in Asp.Net Core Identity will be used.

My IdentityServer4 config:

 public void ConfigureServices(IServiceCollection services)
    {
        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;
        });

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>()
            .AddDefaultUI()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        // configure identity server with in-memory stores, keys, clients and scopes
        services.AddIdentityServer()
            .AddSigningCredential("CN=tst")
            .AddInMemoryPersistedGrants()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddAspNetIdentity<IdentityUser>();
    }


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        //app.UseHttpsRedirection();
        //app.UseCookiePolicy();


        app.UseStaticFiles();
        app.UseIdentityServer();
        app.UseMvcWithDefaultRoute();
        //app.UseMvc(routes =>
        //         {
        //             routes.MapRoute(
        //                 name: "default",
        //                 template: "{controller=Home}/{action=Index}/{id?}");
        //         });
    }

My Client Config:

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication("oidc")
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", optins =>
            {                                       
                optins.SignInScheme = "Cookies";
                optins.Authority = "http://localhost:5000";
                optins.RequireHttpsMetadata = false;

                optins.ClientId = "mvc";
                optins.ClientSecret = "secret";
                optins.ResponseType = "code id_token";
                optins.GetClaimsFromUserInfoEndpoint = true;                    

                optins.Scope.Add("openid");
                optins.Scope.Add("profile");
                //optins.Scope.Add("email");
                optins.Scope.Add("api1");

                optins.ClaimActions.Add(new JsonKeyClaimAction("role", "role", "role"));
                optins.SaveTokens = true;

            });

        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;
        });


        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }


 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();       
        app.UseAuthentication();
        app.UseCookiePolicy();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

There are no errors in the IdentityServer4 console.


Solution

  • With the introduction of ASP.NET Core Identity 2.1, the Views, Controllers, etc are no longer added into a project that is generated using either Visual Studio or the dotnet CLI. Instead, they're provided via a Razor Class Library.

    As part of this change, the old-style URLs such as /Account/Login (shown in your example) have also changed. These are now prefixed with /Identity and are provided via ASP.NET Core Razor Pages that live in an area named Identity.

    IdentityServer4 defaults to using the old-style URLs, which, as I've said, no longer exist (resulting in your 404). To resolve this, configure the IdentityServerOptions object in your code to use the new location(s):

    services.AddIdentityServer(options =>
        {
            options.UserInteraction.LoginUrl = "/Identity/Account/Login";
            options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
        })
        .AddSigningCredential("CN=tst")
        // ...
    

    There are only two Identity-related URLs that can be configured, so I've added them both in the code above for completeness.