Add admin page without full fledged user management

669 views Asked by At

I am building a rather simple site with ASP.NET Core MVC 2.0 that is more or less an image gallery, just for me. I am not using any database so far. It is just a json file with metadata and the image files itself.

Now this site is supposed to get a hidden admin page where I (and only I) can upload new pictures.

What would be a simple but still secure way to add this admin page without having to introduce a full fledged user management to the site? I'd like to avoid to add a database and entity framework etc. to the site - there will only be one user.

In other words, what is a secure and simple way to add user management where there are is only one user that authenticates: Me, the admin.

1

There are 1 answers

2
jamesSampica On

Store a hashed version of your desired username/password in the appsettings.json and then rehash the values provided through the login screen and compare them.

Here's an example of how logging in could be accomplished. This bootstraps off of the default hasher present in Asp.Net Identity but you could use any hashing function.

You might want to create some other helpers too in case you want to reset the hashed password from your application versus having to go into the settings file.

appsettings.json

{
    ...
    "LoginCredentials": {
        "UsernameHash": "AQAAAAEAACcQAAAAENmv+riLvtTIa5wafXxzEX4rMSMXwVzG00q4jZKBI7Lx/oe2PFdqW1r521HBsL567g==",
        "PasswordHash": "AQAAAAEAACcQAAAAEKwwppiixEQM9QO7hOXcoXXgIvHKs9QHRz1k0lAZ3noVwID2lv+I+Dwc9OheqDGFBA=="
    }
}

Startup.cs

 public void ConfigureServices(IServiceCollection services)
 {
    //Assuming services.AddIdentity<...>(...) is not added as a service
    services.Configure<LoginCredentialOptions>(Configuration.GetSection("LoginCredentials"));
    services.AddTransient<IPasswordHasher<User>, PasswordHasher<User>>();
    ...
 }

LoginCredentialOptions.cs

public class LoginCredentialOptions
{
    public string UsernameHash { get; set; }

    public string PasswordHash { get; set; }
}

AccountController.cs

...
public async Task<IActionResult> Login([FromServices] IOptions<LoginCredentialOptions> loginCreds, LoginViewModel model, string returnUrl = null)
{
    if (ModelState.IsValid)
    {
        var passwordResult = passwordHasher.VerifyHashedPassword(null, loginCreds.Value.PasswordHash, model.Password);
        var usernameResult = passwordHasher.VerifyHashedPassword(null, loginCreds.Value.UsernameHash, model.Username);

        if (passwordResult == PasswordVerificationResult.Success &&
            usernameResult == PasswordVerificationResult.Success)
        {
            //Create identity cookie and sign in

            RedirectToAction(nameof(Index), "Home");
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}