Search code examples
asp.net-coreasp.net-core-2.1role-base-authorization

ASP.NET Core 2.1 authentication


I am facing following issue: I am trying to secure my ASP.NET Core Web API by using role-based authentication.

I have added the following lines to ConfigureServices():

// Authorization
services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddDefaultTokenProviders()
        .AddEntityFrameworkStores<ApplicationDbContext>();
services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/api/Account/Login";
        options.AccessDeniedPath = "/api/Account/AccessDenied";
        options.SlidingExpiration = true;
    });

And to Configure():

// Authorization
app.UseAuthentication();

using (var scope = app.ApplicationServices.CreateScope())
{
    CreateRoles(scope.ServiceProvider.GetService<RoleManager<IdentityRole>>()).Wait();
    CreateUsers(scope.ServiceProvider.GetService<UserManager<ApplicationUser>>()).Wait();
}

CreateRoles() and CreateUsers() are working fine: these methods create some roles and an admin user, store them in the corresponding SQL tables and in the user/role manager.

Now I am able to protect my controllers with [Authorize]. Accessing API calls that are tagged with [AllowAnonymous] is possible.

But how can I log in to the API and access the other API calls?

To do that, I have created an account controller as follows:

[Route("/api/Account")]
public class AccountController : Controller
{
    public AccountController()
    {
    }

    [HttpPost]
    [Route("Login")]
    public async Task<IActionResult> Login()
    {
    }
}

I have read many articles on this topic, but I can not get the login up and running. So the goal is to log in with a user stored in the User Manager and access some API calls that require authentication. Could someone try to explain how I can achieve it?


Solution

  • You need to use SignInManager<>.PasswordSignInAsync() to sign in user. It will assign necessary cookies to process authentication. It may look like this:

    public class AccountController : Controller
    {
        private readonly SignInManager<ApplicationUser> _signInManager;
        public AccountController(SignInManager<ApplicationUser> signInManager)
        {
            _signInManager = signInManager;
        }
    
        public async Task<IActionResult> Login(string login, string password)
        {
            var result = await _signInManager.PasswordSignInAsync(login, password, true, lockoutOnFailure: false);
    
            if (result.Succeeded)
            { 
                //process successful result
            }
            else
            {
                //process failed result
            }
        }
    }