Click here to Skip to main content
14,267,453 members

Forms Authentication using Web API

Rate this:
4.62 (11 votes)
Please Sign up or sign in to vote.
4.62 (11 votes)
16 Jun 2015CPOL
If using Identity framework is not possible, one can add the old school forms authentication method.

Introduction

With the advent of OWIN middleware and Identity framework, traditional forms authentication is outdated since OWIN middleware and Identity framework takes care of everything in a better and organized manner. But sometimes, existing applications cannot be migrated to Identity framework due to one or the other reason, but Form Authentication user login is needed. For such situations, here is the workaround.

Background

There was an existing ASP.NET application using role based forms authentication, and was supposed to be migrated to ASP.NET MVC, but for some reason, the client wanted to stick to forms authentication.

Using the Code

To implement forms authentication, interception of both request and response is required which is done with the help of DelegatingHandler.

public class BasicAuthMessageHandler : DelegatingHandler
    {
        private const string BasicAuthResponseHeader = "WWW-Authenticate";
        private const string BasicAuthResponseHeaderValue = "Basic";

        public adminPrincipalProvider PrincipalProvider = new adminPrincipalProvider();

        protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            AuthenticationHeaderValue authValue = request.Headers.Authorization;
            if (authValue != null && authValue.Parameter != "undefined" && 
				!String.IsNullOrWhiteSpace(authValue.Parameter))
            {
                string email = authValue.Parameter;
                if (HttpContext.Current.Session == null || 
		HttpContext.Current.Session["userToken"] == null || 
		string.IsNullOrEmpty(HttpContext.Current.Session["userToken"].ToString()))
                {
                    HttpContext.Current.Session["userToken"] = email;
                }
                else
                {
                    email = HttpContext.Current.Session["userToken"].ToString();
                }

                if (!string.IsNullOrEmpty(email))
                {
                    IPrincipal principalObj = PrincipalProvider.createPrincipal(email, "Admin");
                    Thread.CurrentPrincipal = principalObj;
                    HttpContext.Current.User = principalObj;
                }
            }
            return base.SendAsync(request, cancellationToken)
               .ContinueWith(task =>
               {
                   var response = task.Result;
                   if (response.StatusCode == HttpStatusCode.Unauthorized
                       && !response.Headers.Contains(BasicAuthResponseHeader))
                   {
                       response.Headers.Add(BasicAuthResponseHeader
                           , BasicAuthResponseHeaderValue);
                   }
                   return response;
               });
        }
    }

Principal object is used to assign role to a validated user, this principal object is added to HttpContext's user property.

Controller Login & Logout Web Method

[HttpPost, AllowAnonymous, Route("login")]
 public async Task<HttpResponseMessage> Login([FromBody]LoginRequest request)
 {
     var loginService = new LoginService();
     LoginResponse response = await loginService.LoginAsync(request.username, request.password);
     if (response.Success)
     {
         FormsAuthentication.SetAuthCookie(response.Token, false);
     }
     return Request.CreateResponse(HttpStatusCode.OK, response);
 }

 [HttpPost, AllowAnonymous, Route("logout")]
 public void Signout()
 {
     FormsAuthentication.SignOut();

     if (HttpContext.Current.Session != null)
         HttpContext.Current.Session.Abandon();
 }

To setup role based authorization on webmethods, the following attributes are to be added on the top of web method's implementation.

[HttpGet, Authorize(Roles = "admin"), Route("name")]

Calling from Client

The following jquery code shows how to make a Login call.

$(document).ready(
    function () {
       $("#btnSubmit").click(function () {
          var usrname = $("#username").val();
          var pwd = $("#password").val();
          $.post("http://localhost:50750/api/loginctrl/login", 
		{ username: usrname, password: pwd }, function (result) {
                    alert(JSON.stringify(result));
                });
                       
          });
        });

Registering Delegating Handler

Before starting the execution of the project, custom Delegating Handler is to be registered with Application's Message Handlers. In this app, Delegating handler is registered inside Global.asax's Application_Start method.

protected void Application_Start()
       {
           AreaRegistration.RegisterAllAreas();
           GlobalConfiguration.Configure(WebApiConfig.Register);
           FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
           RouteConfig.RegisterRoutes(RouteTable.Routes);
           BundleConfig.RegisterBundles(BundleTable.Bundles);

           var basicAuthMessageHandler = new WebAPI_FormsAuth.Helper.BasicAuthMessageHandler();
           basicAuthMessageHandler.PrincipalProvider =
           new WebAPI_FormsAuth.Helper.adminPrincipalProvider();
           //start message handler
           GlobalConfiguration.Configuration.MessageHandlers.Add(basicAuthMessageHandler);
       }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

saurabhsharmacs
Software Developer
India India
Saurabh Sharma is a .Net Programmer.

Comments and Discussions

 
QuestionConfused Pin
Christopher Ayroso18-Nov-17 20:31
memberChristopher Ayroso18-Nov-17 20:31 
QuestionNice Article Pin
Santhakumar Munuswamy @ Chennai18-Jun-15 21:56
professionalSanthakumar Munuswamy @ Chennai18-Jun-15 21:56 
QuestionChecking Email Pin
Bill Gerold17-Jun-15 12:41
memberBill Gerold17-Jun-15 12:41 
AnswerRe: Checking Email Pin
saurabhsharmacs22-Jun-15 2:30
membersaurabhsharmacs22-Jun-15 2:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Tip/Trick
Posted 16 Jun 2015

Stats

39.2K views
1.6K downloads
15 bookmarked