asp.net mvc - معالجة مهلة الجلسة في مكالمات ajax




asp.net-mvc asp.net-mvc-3 (6)

على الرغم من أن هذا قد تم الإجابة عليه بشكل جيد ، أعتقد أن هذا هو أقصر وأسرع حل إذا كنت تستخدم .NET 4.5. خاصية صغيرة تسمى SuppressFormsAuthenticationRedirect والتي تمت إضافتها. اضبط على true ولن يؤدي إلى إعادة توجيه 302 إلى صفحة تسجيل الدخول.

http://msdn.microsoft.com/en-us/library/system.web.httpresponse.suppressformsauthenticationredirect.aspx

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        // returns a 401 already
        base.HandleUnauthorizedRequest(filterContext);
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // we simply have to tell mvc not to redirect to login page
            filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
        }
    }
}

بافتراض أنك تخطط للتعامل مع طلبات استدعاء ajax fail / error ، حيث ستحصل على 401 غير مصرح به.

أقوم بإجراء مكالمة ajax باستخدام jquery إلى إجراء تحكم asp.net mvc:

[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult GetWeek(string startDay)
        {
            var daysOfWeek = CompanyUtility.GetWeek(User.Company.Id, startDay);
            return Json(daysOfWeek);
        }

عند انتهاء مهلة الجلسة ، ستفشل هذه المكالمة ، حيث يتم تخزين كائن المستخدم في الجلسة. لقد أنشأت سمة تخويل مخصصة للتحقق من فقدان الجلسة وإعادة التوجيه إلى صفحة تسجيل الدخول. يعمل هذا بشكل جيد لطلبات الصفحة ، ومع ذلك لا يعمل لطلبات ajax ، حيث لا يمكنك إعادة التوجيه من طلب ajax:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AuthorizeUserAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.Request.IsAjaxRequest())
            {//validate http request.
                if (!httpContext.Request.IsAuthenticated
                    || httpContext.Session["User"] == null)
                {
                    FormsAuthentication.SignOut();
                    httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
                    return false;
                }
            }
            return true;
        }
    }

قرأت على مؤشر ترابط آخر أنه عندما لا يكون المستخدم مصادقًا وأنت تقدم طلبًا للحصول على ajax ، يجب عليك تعيين رمز الحالة على 401 (غير مصرح به) ثم التحقق من ذلك في js وإعادة توجيهه إلى صفحة تسجيل الدخول. ومع ذلك ، لا يمكنني الحصول على هذا العمل:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
            {
                filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
            }
            else
            {
                base.OnActionExecuting(filterContext);
            }
        }

بشكل أساسي ، سيتم تعيينه إلى 401 ، ولكن بعد ذلك سيستمر في إجراء وحدة التحكم وإلقاء كائن مرجع لم يتم تعيينه لمثيل خطأ في الكائن ، والذي يقوم بعد ذلك بإرجاع الخطأ 500 إلى js العميل. إذا قمت بتغيير سمة التخويل المخصصة الخاصة بي للتحقق من صحة طلبات ajax وإرجاعها كاذبة لتلك التي لم تتم المصادقة عليها ، فإن ذلك يجعل طلب ajax بإرجاع صفحة تسجيل الدخول الخاصة بي ، والتي من الواضح أنها لا تعمل.

كيف يمكنني الحصول على هذا العمل؟


على مكالمة ajax إذا انتهت صلاحية الجلسة بإعادة شيء من هذا القبيل

<script>
$(function(){
    location.reload();
});
</script>

هاها ...


قد ترغب في محاولة رمي HttpException والتقاطها في javascript الخاص بك.

throw new HttpException(401, "Auth Failed")

كنت أواجه مشكلة مماثلة ووجدت this

بدلاً من إرجاع أي JSON ، فقط قبل إرسال الاستجابة مرة أخرى ، فرض ASP.NET لإرجاع رمز 401. في Global.asax :

protected void Application_EndRequest()
    {
        var context = new HttpContextWrapper(Context);
        if (context.Request.IsAjaxRequest() && context.Response.StatusCode == 302)
        {
            Context.Response.Clear();
            Context.Response.Write("**custom error message**");
            Context.Response.StatusCode = 401;
        }
    }

ثم يمكنك السماح للعميل التعامل معها في JavaScript / jQuery أو أي شيء تستخدمه


هنا كيف أتعامل مع هذا بطريقة بسيطة للغاية في التفويض المخصص ، أتحقق من انتهاء الجلسة ومعالجتها على أنها غير مخولة باستخدام عنصر منطقي للتحقق مما إذا كانت مصادقة فعلاً ولكنها غير مخولة (لإعادة التوجيه إلى صفحة غير مخولة) أو لم يتم توثيقها بسبب انتهاء وقت الجلسة (إعادة التوجيه إلى تسجيل الدخول)

 private bool ispha_LoggedIn = false;
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        ispha_LoggedIn = false;
        var session = httpContext.Session;
        bool authorize = false;
        if (httpContext.Session["authenticationInfo"] == null)
        {

            return authorize;
        }

        using (OrchtechHR_MVCEntities db = new OrchtechHR_MVCEntities())
        {
            UserAuthenticationController UM = new UserAuthenticationController();
            foreach (var roles in userAssignedRoles)
            {
                authorize = UM.IsUserInRole(httpContext.User.Identity.Name, roles);

                if (authorize)
                {

                    return authorize;
                }

            }
        }
        ispha_LoggedIn = true;
        return authorize;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (ispha_LoggedIn==false)
        {
            filterContext.Result = new RedirectResult("~/UserAuthentication/LogIn");
        }
        else
        {
            filterContext.Result = new RedirectResult("~/Dashboard/UnAuthorized");
        }


    }

نأمل إذا كان هذا يرشد شخص ما ، واذا كان هناك تعليقاتهم عن تقديره لمعرفة ذلك على الرغم من.


يمكنك كتابة سمة [Authorize] مخصصة والتي ستُرجع JSON بدلاً من طرح استثناء 401 في حالة الوصول غير المصرح به مما يسمح للبرامج النصية للعميل بمعالجة السيناريو بأمان:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new JsonResult
            {
                Data = new 
                { 
                    // put whatever data you want which will be sent
                    // to the client
                    message = "sorry, but you were logged out" 
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

ثم تزيين جهاز التحكم الخاص بك / الإجراءات معه وعلى العميل:

$.get('@Url.Action("SomeAction")', function (result) {
    if (result.message) {
        alert(result.message);
    } else {
        // do whatever you were doing before with the results
    }
});




authorize-attribute