Jquery 纯ajax MVC4身份验证

Jquery 纯ajax MVC4身份验证,jquery,asp.net-mvc-4,single-page-application,Jquery,Asp.net Mvc 4,Single Page Application,我正在使用MVC4构建一个单页应用程序。为了实现登录功能,我将jquery ajax发布到以下操作: [HttpPost] [AllowAnonymous] public JsonResult JsonLogin(LogInFormViewModel form) { ... //If user authenticates formAuthentication.SetAuthCookie(this.HttpCon

我正在使用MVC4构建一个单页应用程序。为了实现登录功能,我将jquery ajax发布到以下操作:

    [HttpPost] [AllowAnonymous]
    public JsonResult JsonLogin(LogInFormViewModel form)
    {
         ...

         //If user authenticates
            formAuthentication.SetAuthCookie(this.HttpContext,
                                                 UserAuthenticationTicketBuilder.CreateAuthenticationTicket(
                                                                 user));
            return Json(new { success = true, viewResult = this.RenderPartialView("UserStatusBar", null) });

         ...

    }
RenderPartialView()
是一个自定义扩展,它只将我的razor局部视图渲染为字符串

“UserStatusBar”是任何网站顶部的标准栏,如果用户未经身份验证,则显示登录/注册;如果用户:

@if (Request.IsAuthenticated)
{
    <div id="LoggedIn">
        <a class="logoutLink" href="#">Log out</a>
        <span>Welcome, @User.Identity.Name</span>
    </div>
} else {
    <div id="notLoggedIn">
        <a class="loginLink popupLink" href="#">Log in</a>
        <a class="registerLink popupLink" href="#">Register</a>
    </div>
}
唯一的问题是,每当代码进入我的自定义扩展名
RenderPartialView()
请求。IsAuthenticated
仍然与ajax调用之前相同,因此它在下一个请求之前不会重新呈现正确的状态栏

既然
请求。IsAuthenticated
是只读的,我不能在设置授权cookie后简单地设置它,我该如何解决这个问题。我唯一能做的就是设置TempData属性,并在呈现UserStatusBar时检查:

@if (Request.IsAuthenticated || (TempData["AjaxAuthenticated"] != null && (bool)TempData["AjaxAuthenticated"]))
{
    <logged in html>
} else <logged out html>
@if(Request.IsAuthenticated | | |(TempData[“AjaxAuthenticated”]!=null&(bool)TempData[“AjaxAuthenticated”])
{
}否则
但这是有问题的,因为注销时会发生相反的情况<重新呈现状态栏时,
formsAuthentication.SignOut()
之后,
请求.IsAuthenticated
仍然为真,并且在下次请求之前,它再次呈现状态栏的错误标记


我似乎想不出一个办法来解决这个问题,因为我还需要永久链接来处理请求。在这种情况下,我会查看IsAuthenticated。

好的,我找到了答案。我编写了一个控制器扩展,它基于当前响应中的cookie(在成功授权之后和调用此方法之前设置)为当前请求续订安全主体。这将更新
请求。IsAuthenticated
立即为true

注意:我使用的是自定义成员身份,因此此代码不适用于您

    public static void AjaxRenewPrincipal(this Controller controller)
    {
        HttpCookie authCookie = controller.HttpContext.Response.Cookies[FormsAuthentication.FormsCookieName];
        if (IsValidAuthCookie(authCookie))
        {
            var formsAuthentication = DependencyResolver.Current.GetService<IFormsAuthentication>();
            var authTicket = formsAuthentication.Decrypt(authCookie.Value);

            CustomUser user = new CustomUser(authTicket); //An authenticated user
            string[] userRoles = { user.RoleName };
            controller.HttpContext.User = new GenericPrincipal(user , userRoles);
            formsAuthentication.SetAuthCookie(controller.HttpContext, authTicket);
        }
        else
        {
            //using Parameter-less constructor on my CustomClass : IIdentity sets IsAuthenticated to false on the IIdentity, then unauthenticated user gets set to the security principal
            controller.HttpContext.User = new GenericPrincipal(new CustomUser (), new string[] {});
        }
    }
公共静态无效AjaxRenewPrincipal(此控制器)
{
HttpCookie authCookie=controller.HttpContext.Response.Cookie[FormsAuthentication.FormScookeName];
if(IsValidAuthCookie(authCookie))
{
var formsAuthentication=DependencyResolver.Current.GetService();
var authTicket=formsAuthentication.Decrypt(authCookie.Value);
CustomUser=新CustomUser(authTicket);//经过身份验证的用户
字符串[]userRoles={user.RoleName};
controller.HttpContext.User=新的GenericPrincipal(用户,用户角色);
formsAuthentication.SetAuthCookie(controller.HttpContext,authTicket);
}
其他的
{
//在我的CustomClass上使用无参数构造函数:IIdentity集合在IIdentity上被验证为false,然后未经验证的用户被设置为安全主体
controller.HttpContext.User=新的GenericPrincipal(新的CustomUser(),新的字符串[]{});
}
}

好的,我找到了答案。我编写了一个控制器扩展,它基于当前响应中的cookie(在成功授权之后和调用此方法之前设置)为当前请求续订安全主体。这将更新
请求。IsAuthenticated
立即为true

注意:我使用的是自定义成员身份,因此此代码不适用于您

    public static void AjaxRenewPrincipal(this Controller controller)
    {
        HttpCookie authCookie = controller.HttpContext.Response.Cookies[FormsAuthentication.FormsCookieName];
        if (IsValidAuthCookie(authCookie))
        {
            var formsAuthentication = DependencyResolver.Current.GetService<IFormsAuthentication>();
            var authTicket = formsAuthentication.Decrypt(authCookie.Value);

            CustomUser user = new CustomUser(authTicket); //An authenticated user
            string[] userRoles = { user.RoleName };
            controller.HttpContext.User = new GenericPrincipal(user , userRoles);
            formsAuthentication.SetAuthCookie(controller.HttpContext, authTicket);
        }
        else
        {
            //using Parameter-less constructor on my CustomClass : IIdentity sets IsAuthenticated to false on the IIdentity, then unauthenticated user gets set to the security principal
            controller.HttpContext.User = new GenericPrincipal(new CustomUser (), new string[] {});
        }
    }
公共静态无效AjaxRenewPrincipal(此控制器)
{
HttpCookie authCookie=controller.HttpContext.Response.Cookie[FormsAuthentication.FormScookeName];
if(IsValidAuthCookie(authCookie))
{
var formsAuthentication=DependencyResolver.Current.GetService();
var authTicket=formsAuthentication.Decrypt(authCookie.Value);
CustomUser=新CustomUser(authTicket);//经过身份验证的用户
字符串[]userRoles={user.RoleName};
controller.HttpContext.User=新的GenericPrincipal(用户,用户角色);
formsAuthentication.SetAuthCookie(controller.HttpContext,authTicket);
}
其他的
{
//在我的CustomClass上使用无参数构造函数:IIdentity集合在IIdentity上被验证为false,然后未经验证的用户被设置为安全主体
controller.HttpContext.User=新的GenericPrincipal(新的CustomUser(),新的字符串[]{});
}
}