Skip to content

Instantly share code, notes, and snippets.

@amcdnl
Last active November 15, 2020 23:35
Show Gist options
  • Save amcdnl/8239023 to your computer and use it in GitHub Desktop.
Save amcdnl/8239023 to your computer and use it in GitHub Desktop.

Owin Authentication with Web API 2

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.

API > AccountController.cs

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

API > Account.cs

namespace API.Models
{
    public class Account
    {
        public string Username { get; set; }

        public string Password { get; set; }
    }
}

MyProj > Startup.cs

[assembly: OwinStartup(typeof(MyProj.Startup))]
namespace MyProj
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            ConfigureSignalR(app);
        }
    }
}

MyProj > Startup.Auth.cs

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!

@igeoghegan
Copy link

You sir, made my day. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment