Asp.net Core Authentication Example

In this tutorial I will explain how to write custom database authentication in asp.net core like we often use in any web application login page, and at the end of this post i will also explain how we can configure authentication as service known as Identity utility and claims based authentication in asp.net core application.

Here we wite a custom database authentication in asp.net core web application.

database authentication

From user interface to controller, then calling service and data access layer, finally to make call to database.

Asp.net Core Database Authentication

Just think of situation when you have to write a simple login page, where user will enter username and password and hit the login button, you need to check if the credential is matching values in database, if yes, then let the user to be redirected to control panel else show error message.

Step 1:
First, We have to create Model View and Controller.

Model:
Here is my model class with Username, password and User object properties; you can add additional properties as per your requirement.

public class UserModel
{
    public string Username { get; set; }
    public string Password { get; set; }
    public User User { get; set; }
}

View:
Create a razor view with and design a login form, where user can enter username and password. In this example, I have created user folder under views, and index page I have designed the below form

<form asp-controller="user" asp-action="index" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
    <label asp-for="Username" class="control-label"></label>
    <input asp-for="Username" class="form-control" />
    <span asp-validation-for="Username" class="text-danger"></span>
</div>
<div class="form-group">
    <label asp-for="Password" class="control-label"></label>
    <input asp-for="Password" class="form-control" type="password" />
    <span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
    <input type="submit" value="Login" class="btn-lg btn-default btn-primary" />
</div>
</form>

Controller:
Create a user controller class with get and post ActionResult, in post method we write the code to handle authentication based on posted data.

public class userController : Controller
{
    public IActionResult index()
    {
        UserModel model = new UserModel();

        return View(model);
    }

    [HttpPost]
    public IActionResult index(UserModel model)
    {
        // Here will implement authentication code

        return View(model);
    }
}

Step 2:
Now we need to create the business entity, here in our case user object, this object will work a mediator between model data and database object.

Create a simple User class with username, password and some basic details like example below.

public class User
{
    public string Username { get; set; }
    public string Password { get; set; }
    public int UserId { get; set; }
    public string FullName { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string Mobile { get; set; }
    public Policy Policy { get; set; }
    public IList<Role> Roles { get; set; }
    public string AuthenticationSchemes { get; set; }
}

Step 3:
Now create a service class with a method GetUser, on successful authentication the method will return a user object as described above.

public interface IAuthService
{
    User GetUser(string username, string password);
    User GetUser(string username);
}


public class AuthService : IAuthService
{
    public User GetUser(string username, string password)
    {
        UserDTO dto = new UserDTO();
        return dto.GetUser(username, password);
    }
    public User GetUser(string username)
    {
        UserDTO dto = new UserDTO();
        return dto.GetUser(username);
    }
}

UserDTO is data transfer class, where we talk to database, in this class we can write ADO.net code or Entity Framework code to fetch and post data into database.

Below is the example of UserDTO class, I have a hardcoded user object, you can change that with your database values.

public class UserDTO
{
    public User GetUser(string username, string password)
    {
        User u = null;
        if (username == "user1")
        {
            u = new User();
            u.Username = "user1";
            u.FullName = "Bill Rose";
            u.Address = "California";
            u.Email = "bill@webtrainingroom.com";
        }
        return u;
    }
    public User GetUser(string username)
    {
        User u = null;
        if (username == "user1")
        {
            u = new User();
            u.Username = "user1";
            u.FullName = "Bill Rose";
            u.Address = "California";
            u.Email = "bill@webtrainingroom.com";
        }
        return u;
    }
}

If you are using entity framework, then in above method your code may look like example below.

using (var context = new WTRDBContext())
{ tbUser _u = context.tbUser
.Where(s => s.Username == username && s.Password == password)
        .FirstOrDefault<tbUser>();
}

So far we have created all required objects and methods we need to perform authentication, now we register the service and implement the service in controller class, so data posted from view can communicate back and forth.

Step 4:
Register the service and implement dependency injection through controller, so we can access all service methods.

Now open your startup.cs file and register the service, here I have used AddSingleton method to register the service, that means IOC container will create a single instance of service class and serve throughout the lifetime.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IAuthService, AuthService>();
}

Create service instance in controller to perform authentication.

Notice, how the service IAuthService instance created through dependency injection, then at post method we are calling the _authService.GetUser(model.Username, model.Password); to check user details from database.

If user found then, means authentication successful, then user will be redirected to control panel, else to auth-failed view.

public class userController : Controller
{

    IAuthService _authService;
    public userController(IAuthService authservice)
    {
        _authService = authservice;
    }

    public IActionResult index()
    {
        UserModel model = new UserModel();
        return View(model);
    }

    [HttpPost]
    public IActionResult index(UserModel model)
    {
        User u= _authService.GetUser(model.Username, model.Password);
        if (u != null)
        {
            SessionHelper.SetObjectAsJson(HttpContext.Session, "userObject", u);
            return RedirectToAction("controlpanel");
        }
        else 
        {
            return RedirectToAction("auth-failed");
        }
        return View(model);
    }
}

On successful authentication, we are storing the user information into a session object. SessionHelper.SetObjectAsJson(HttpContext.Session, "userObject", u);

Check Authorization

Now, you may also check authorization of authenticated user, once user try to access different area of your application, you can check authorization based on property values available in user.Roles IList<Role> Roles property, Probably you can write an additional method isInRole(IList<Role> roles, string expectedRole), which should returns a boolean value, that way it will be easy to call from multiple location wherever you want to check the user role.

You may be interested to read following tutorials

Asp.Net Core C# Examples | Join Asp.Net MVC Course