Using Microsoft.Owin.Security
along with .NET Web API 2 for authentication on Single Page Applications.
My example is split up into 2 different projects, API which is WebAPI2 project and MyProj which is a basic MVC that contains primarily only JavaScript/CSS/etc and the startup classes.
namespace API
{
public class AccountController : ApiController
{
public AccountController()
{
// Supress redirection for web services
HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true;
}
[HttpPost]
[AllowAnonymous]
[Route("api/account/login")]
public HttpResponseMessage Login(Account login)
{
var authenticated = false;
// do your magic checking here ...
if(!String.IsNullOrEmpty(login.Domain)){
var ad = new ActiveDirectoryMembershipProvider();
authenticated = ad.ValidateUser(login.Username, login.Password);
} else {
var config = WebConfigurationManager.AppSettings["AdminLogin"];
var split = config.Split(',');
authenticated = login.Username ==
split[0] && login.Password == split[1];
}
if (authenticated)
{
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Email, login.Username));
var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignIn(id);
return Request.CreateResponse(HttpStatusCode.OK);
}
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
[HttpGet]
[Route("api/account/profile")]
[Authorize]
public HttpResponseMessage Profile()
{
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<object>(new
{
UserName = User.Identity.Name
}, Configuration.Formatters.JsonFormatter)
};
}
[HttpPost]
[Route("api/account/logout")]
[Authorize]
public HttpResponseMessage Logout()
{
var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignOut();
return Request.CreateResponse(HttpStatusCode.OK);
}
}
}
namespace API.Models
{
public class Account
{
public string Username { get; set; }
public string Password { get; set; }
}
}
[assembly: OwinStartup(typeof(MyProj.Startup))]
namespace MyProj
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
ConfigureSignalR(app);
}
}
}
namespace MyProj
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
AuthenticationMode = AuthenticationMode.Active
});
}
}
}
this setup will create a cookie on your browser after authenticated that looks like:
.AspNET.ApplicationCookie nYS_YhEkkN12Qkjk_5ZlmfyTon4_Z80DGS
from there I used AngularJS to call back and forth but you can use jQuery or whatever but basically you need to set withCredentials
property like:
app.config(["$httpProvider", function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]);
and presto!
You sir, made my day. Thank you.