Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My AspNet Core 3.1 Identity Pages give a 404 in IdentityServer4. How can I access these? Is this a route problem?

I have followed the Deblokt tutorial here which explains in great detail how to set up IdentityServer4 in .net core 3.1 and use AspNetCore Identity for the user store.

I can log in to my IdentityServer from the https://localhost:5001/Account/Login url (and logout) just fine... But I cannot access the AspNet Core Identity pages (eg Register/ForgotPassword/AccessDenied etc). I have scaffolded them out, so they sit under Areas/Identity/Pages/Account... but when I navigate to them, eg https://localhost:5001/Identity/Account/Register, I just get a 404 not found.

I'm not sure, but suspect this could be a routing issue, so I have researched providing routing for these pages, but the examples I have seen for IdentityServer are for Core2.1 and use the app.UseMVC ... which my startup does not have. I have tried to include it, but I get error saying

Endpoint Routing does not support 'IApplicationBuilder.UseMvc(...)'. To use 'IApplicationBuilder.UseMvc' set 'MvcOptions.EnableEndpointRouting = false' inside 'ConfigureServices(...)'

So where do I go from here?

I downloaded the tutorials accompanying solution from GitHub, but it is a Core 2.1 solution, so suspect the tutorial is a rewrite/upgraded version to 3.1.

This is my Startup file...

public class Startup
{

        public IWebHostEnvironment Environment { get; }
        public IConfiguration Configuration { get; }
        public Startup(IWebHostEnvironment environment, IConfiguration configuration)
        {
            Environment = environment;
            Configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            // uncomment, if you want to add an MVC-based UI
            services.AddControllersWithViews();
            services.AddRazorPages(); // I recently added this, but made no difference

            string connectionString = Configuration.GetConnectionString("DefaultConnection");

            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

            services.AddDbContext<IdentityDbContext>(options =>
                options.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly))
            );

            services.AddDbContext<Data.ConfigurationDbContext>(options => options.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly)));

            services.AddIdentity<ApplicationUser, IdentityRole>(options =>
            {
                options.SignIn.RequireConfirmedEmail = true;
            })
            .AddEntityFrameworkStores<IdentityDbContext>()
            .AddDefaultTokenProviders();

            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
                options.UserInteraction.LoginUrl = "/Account/Login";
                options.UserInteraction.LogoutUrl = "/Account/Logout";
                options.Authentication = new AuthenticationOptions()
                {
                    CookieLifetime = TimeSpan.FromHours(10), // ID server cookie timeout set to 10 hours
                    CookieSlidingExpiration = true
                };
            })
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
            })
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
                options.EnableTokenCleanup = true;
            })
            .AddAspNetIdentity<ApplicationUser>();

            X509Certificate2 cert = null;

            using (X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
            {
                certStore.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certCollection = certStore.Certificates.Find(
                    X509FindType.FindByThumbprint,
                    // Replace below with your cert's thumbprint
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // Replaced for this post
                    ,
                    false);
                // Get the first cert with the thumbprint
                if (certCollection.Count > 0)
                {
                    cert = certCollection[0];
                }
            }

            // Fallback to local file for development
            if (cert == null)
            {
                cert = new X509Certificate2(Path.Combine(Environment.ContentRootPath, "xxxxxxxxx.pfx"), "xxxxxxxxxxxxxxxxxxxxx"); // Replaced for this post
            }

            // not recommended for production - you need to store your key material somewhere secure
            //builder.AddDeveloperSigningCredential();
            builder.AddSigningCredential(cert);
            builder.AddValidationKey(cert);

            services.AddScoped<IProfileService, ProfileService>();

        }

        public void Configure(IApplicationBuilder app)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // uncomment if you want to add MVC
            app.UseStaticFiles();
            app.UseRouting();

            app.UseIdentityServer();

            // uncomment, if you want to add MVC
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }
    }
}
like image 509
Craig Avatar asked Jun 17 '20 20:06

Craig


People also ask

What is ASP.NET Core identity used for?

ASP.NET Core Identity: Is an API that supports user interface (UI) login functionality. Manages users, passwords, profile data, roles, claims, tokens, email confirmation, and more.

Is Identity Server 4 open source?

About IdentityServer4IdentityServer is a free, open source OpenID Connect and OAuth 2.0 framework for ASP.NET Core.

What is Identity Server in ASP.NET Core?

IdentityServer is an authentication server that implements OpenID Connect (OIDC) and OAuth 2.0 standards for ASP.NET Core. It's designed to provide a common way to authenticate requests to all of your applications, whether they're web, native, mobile, or API endpoints.

What is Aspnet identity?

ASP.NET Identity is Microsoft's user management library for ASP.NET. It includes functionality such as password hashing, password validation, user storage, and claims management. It usually also comes with some basic authentication, bringing its own cookies and multi-factor authentication to the party.


1 Answers

Well, it was 1 line of code in my startup.cs file

app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute();
    endpoints.MapRazorPages(); // This one!
});

Oh and another error occurred on the register page if anyone comes across it.

Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UI.Services.IEmailSender'

just add the following line of code to the end of your ConfigureServices method in Startup.cs

services.AddTransient<IEmailSender,SomeEmailSender>();

The IEmailSender is from Microsoft.AspNetCore.Identity.UI.Services. Just create a class that implements this interface and declare it here.

like image 131
Craig Avatar answered Oct 01 '22 13:10

Craig