Daniel Congrove
Daniel Congrove

Reputation: 3679

ASP.NET Core 2.1 Identity: How to remove the Default UI razor pages?

Expanding the answer in this question: Change routing in ASP.NET Core Identity UI?

Javier recommends one of the following options when wanting to customise the URLs:

  • Use the scaffolding element of the Default UI and make all necessary customisations yourself.
  • Use a redirection rule that points the old routes to the new routes.
  • Don't use the Default UI at all.

From a new ASP.NET Core 2.1 MVC project, with Authentication: Individual User Accounts set, how do you NOT use the Default UI? It seems to be installed by default with Identity Core.

enter image description here

After the project is created, what is the method to remove the Default UI razor pages, and still use Identity Core?

Can I just delete the /Identity/ area, and create my own AccountController instead?

Upvotes: 30

Views: 23958

Answers (4)

Alamakanambra
Alamakanambra

Reputation: 7871

Maybe this is sufficient solution - don't let user access the Identity pages:

//program.cs

app.Use(async (context, next) =>
{
    await next();
    if (context.Request.Path.StartsWithSegments("/Identity"))
    {
        context.Response.Redirect("/");// redirect to index
        return;
    }
});

Upvotes: 1

hivie7510
hivie7510

Reputation: 1246

A little late, but there is a much easier way to do it. You can add new scaffolding to override everything. Check out this article.

Upvotes: 5

Daniel Congrove
Daniel Congrove

Reputation: 3679

Using the article linked by Panagiotis Kanavos, I was able to reach a solution.

From the ASP.NET Core 2.1.0-preview1, there was a line .AddDefaultUI(), which you didn't have to include in Startup.cs.

services.AddIdentity<IdentityUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultUI()
    .AddDefaultTokenProviders();

In the final release version of Core 2.1 however, the same section was simplified to:

services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

The solution, if you change AddDefaultIdentity back to AddIdentity, you can override the defaults. I.E. don't include .AddDefaultUI() (and also don't scaffold the UI) and you can write your own.

services.AddIdentity<IdentityUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
    .AddEntityFrameworkStores<ApplicationDbContext>()
    // .AddDefaultUI()
    .AddDefaultTokenProviders();

Then, I think it's safe to delete the /Areas/Identity/ folder, but I'm not 100%

Update:

I cleaned up my answer to detail the final solution I ended up going with, to remove the default identity UI razor pages that come with ASP.NET Core 2.1 and and use MVC instead.

1) In Startup.cs,

    public void ConfigureServices(IServiceCollection services)
    {
        // Unrelated stuff commented out...

        // BEGIN: Identity Setup (Overrides default identity)
        services.AddIdentity<ApplicationUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        // END: Identity Setup

        services.Configure<IdentityOptions>(options =>
        {
            // Set your identity Settings here (password length, etc.)
        });

        // More unrelated stuff commented out...

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

        // Added after AddMvc()
        services.ConfigureApplicationCookie(options =>
        {
            options.LoginPath = $"/account/login";
            options.LogoutPath = $"/account/logout";
            options.AccessDeniedPath = $"/account/access-denied";
        });

        // More unrelated stuff commented out...
    }

And obviously, replace both ApplicationUser, and IdentityRole with your own classes if required.

2) Delete the Area folder for Identity that came default with your ASP.NET Core 2.1 project.

3) Create a new separate ASP.NET Core 2.0 project (not "2.1"), with Individual User Account authentication selected in the project creation window.

4) Copy the AccountController and ManageController, with the corresponding ViewModels and Views, from the 2.0 project to your ASP.NET Core 2.1 project.

Doing the above, I haven't run into any issues so far.

Upvotes: 38

Ryan Dines
Ryan Dines

Reputation: 1037

I upvoted the first answer because it got me 90 percent there, wanted to give out the rest (it was a little too long to put in the comments). So you'll want to keep that /Areas/Identity/ folder because it points to your shared folder if you happen to be using the header from the default template, if not it doesn't matter, delete it. The backend will still point to Identity/Account/Register/, so create a controller called Account make a folder in views called Account and put the Register.cshtml. I took the original html from a debugger window that you can use as a template to customize. Put inside Register.cshtml:

<div class="container body-content">


<h2>Register</h2>

<div class="row">
    <div class="col-md-4">
        <form method="post" action="/Identity/Account/Register" novalidate="novalidate">
            <h4>Create a new account.</h4>
            <hr>
            <div class="text-danger validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>
</ul></div>
            <div class="form-group">
                <label for="Input_Email">Email</label>
                <input class="form-control" type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Input_Email" name="Input.Email" value="">
                <span class="text-danger field-validation-valid" data-valmsg-for="Input.Email" data-valmsg-replace="true"></span>
            </div>
            <div class="form-group">
                <label for="Input_Password">Password</label>
                <input class="form-control" type="password" data-val="true" data-val-length="The Password must be at least 6 and at max 100 characters long." data-val-length-max="100" data-val-length-min="6" data-val-required="The Password field is required." id="Input_Password" name="Input.Password">
                <span class="text-danger field-validation-valid" data-valmsg-for="Input.Password" data-valmsg-replace="true"></span>
            </div>
            <div class="form-group">
                <label for="Input_ConfirmPassword">Confirm password</label>
                <input class="form-control" type="password" data-val="true" data-val-equalto="The password and confirmation password do not match." data-val-equalto-other="*.Password" id="Input_ConfirmPassword" name="Input.ConfirmPassword">
                <span class="text-danger field-validation-valid" data-valmsg-for="Input.ConfirmPassword" data-valmsg-replace="true"></span>
            </div>
            <button type="submit" class="btn btn-default">Register</button>
        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8IWbPHM_NTJDv_7HGewWzbbRveP09yQOznYdTWL2aN5X_4_eVbNE1w8D_qz7zegloVtdAhuVOJbJLQo0ja73FB3PgYycyGpn-DfX3fJqv4Cx8ns6Ygh6M7nMxV0eozO7hoDxUfPwrIJb2RcFtyzhPpMevZ4P0M8aVyBP55SP-5C4l23dCtDXXUOAY_YLwt67dw"></form>
    </div>
</div>


        <hr>
        <footer>
            <p>© 2018 - SqlServerApp</p>
        </footer>
    </div> 

Like the other answer says, alter Startup:

services.AddIdentity<IdentityUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
    .AddEntityFrameworkStores<ApplicationDbContext>()
    // .AddDefaultUI()
    .AddDefaultTokenProviders();

Also gotta make the route to your controller, same Startup.cs file, keep the other route that's in there, probably keep it first now that I think about it, since it checks them sequentially:

app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "identity",
                template: "Identity/{controller=Account}/{action=Register}/{id?}");

Upvotes: 3

Related Questions