اعتبارسنجی فرم توسط Web API

اگر استفاده از فریم ورک Identity امکان پذیر نبود استفاده از روش قدیمی متد اعتبار سنجی فرم می تواند مفید باشد. در این مقاله با نحوه اعتبارسنجی فرم توسط Web API آشنا خواهید شد.

اعتبارسنجی فرم توسط Web API

مقدمه

با ظهور OWIN و فریم ورک Identity روش های قدیمی اعتبارسنجی فرم منسوخ شدند چرا که آنها از همه چیز مراقبت به شیوه ای بهتر و سازمان یافته تری دارند. اما گاهی برنامه های موجود نمی توانند به یک یا چند دلیل به فریم ورک Identity مهاجرت کنند اما اعتبارسنجی فرم Login کاربر الزامی است. در این صورت آن را بررسی خواهیم کرد.

پیش زمینه

در این جا یک برنامه ASP.NET که دارای اعتبار سنجی فرم بر مبنای Role هر کاربر (RoleBased) موجود است و قرار است به ASP.NET MVC مهاجرت کند. اما بنا به دلایلی کاربر می خواهد forms authentication بماند.

دستورات

برای پیاده سازی forms authentication ، برای رهگیری از درخواست و هم پاسخ مورد نیاز است که این کار با کمک 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 برای اختصاص دادن Role به کاربر های معتبر مورد استفاده قرار می گیرد. این شیء Principal به خاصیت HttpContext کاربر اختصاص داده می شود.

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

برای نصب role based authorization روی webmethods خاصیت زیر در ابتدای تعریف webmethods اضافه می شود.

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

Calling from Client

کد jquery زیر نحوه Login کردن نمایش داده می شود.

$(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

قبل از شروع اجرای پروژه Delegating Handler سفارشی با Application's Message Handlers ثبت می شود. در این برنامه Delegating handler درون متد Application_Start در Global.asax تعریف می شود.

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

 

فایل های ضمیمه