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