I have a nice ASP.NET 5 / MVC 6 app up and running. Essentially for this purpose it is just the normal sample app you get when you start a new project to keep it simple. So far I can:
- Register a user
- Login
- Logout
- Protect a page (forcing login etc)
Now, what I would like is to provide an API mechanism for a app to login and get an authentication token. Specifically I am working on two mobile apps to test with, one using Angular / Cordova and one using Xamarin.
I have looked high and low and I cannot seem to find an example yet that shows how to make this work. Every example I find so far assumes the user will login via the normal web form / post cycle and then be taken to a page that loads Angular and this the authentication token is already in the browser.
The relevant code from the AccountController.cs file for the MVC controller is below. What I ultimately want is the equivalent functionality but from a pure API call that allows Angular / Xamarin to send it a username / password and get back a authentication token or failure.
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewBag.ReturnUrl = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
if (result.Succeeded)
{
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
}
if (result.IsLockedOut)
{
return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
What is the recommended way to protect a Web API using ASP.NET MVC 6?
I think the recommended approach for securing WebApi2 is through an Authorisation Server. The Authorisation Server takes care of generating tokens. But based on this, the OAuth2 based authorization server that is part of Katana3 has been dropped from Asp.Net 5.
I assume your app is not a live app yet, since both ASP.NET 5 and MVC 6 are not in their final release stage yet. So if you are okay to change your identity/authentication process, you could use Thinktecture's IdentityServer3.
Dominick Baier has blogged about the The State of Security on ASP.NET 5 and MVC 6 and where IdSvr3 comes into the picture. That blog has a link to a Github repository for sample API Controller, and also a API client. It also has sample for an MVC Web app. And it can work with Asp.Net Identity.
UPDATE:
If that does not work for you, you could try AspNet.Security.OpenIdConnect.Server. Note that it has open issues on Github, so you may encounter problems using it. Note also its dependencies, particularly the azureadwebstacknightly.
Please note that ASP.NET 5 and MVC 6 may be in a stable beta release, but they are still in beta release. It could still change.
Also, IdSvr3 v2.0 may be in its final release, but it is developed by a separate team. And it is only been released 2 weeks ago, so IMHO like most software, you can encounter things that may likely missed their tests. Note the ASP.NET Team, last week, tweeted about IdSvr3's (v2.0) release, so it appears they are endorsing it.