2
votes

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?

1

1 Answers

2
votes

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
        }
    }
}