2012-12-18 2 views
1

나는이 작업에 JQuery와 아약스 POST를 할 기능에 로그인을 위해 MVC (4)를 사용하여 단일 페이지 응용 프로그램을 짓고 있어요 :순수 아약스 MVC 4 인증

[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() 그냥 렌더링 사용자 정의 확장 내 면도칼 부분보기 문자열.

은 "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> 
} 

I 비동기 또는 해제 사용자가 로그인 한 후 바로 사용자의 상태 표시 줄을 다시 렌더링하기 위해 같은 것을 할 :

success: function (result) { 
    if (result.success) { 
     $('#userStatusBar').empty().html(result.viewResult, null); 
    } 
} 

유일한 문제는, 내 사용자 지정 확장 RenderPartialView()에 코드 단계, Request.IsAuthenticated 여전히 같은 때마다 이전 t o ajax 호출이므로 다음 요청 때까지 올바른 상태 표시 줄을 다시 렌더링하지 않습니다.

Request.IsAuthenticated이 읽기 ​​전용이므로 권한 부여 쿠키를 설정 한 후에 설정할 수 없습니다. 내가 대신 TempData 속성을 설정하고 렌더링 대신 UserStatusBar 확인됩니다 할 수있는 유일한 :

@if (Request.IsAuthenticated || (TempData["AjaxAuthenticated"] != null && (bool)TempData["AjaxAuthenticated"])) 
{ 
    <logged in html> 
} else <logged out html> 

을하지만 로그 오프 할 때 반대가 발생하기 때문에이 문제가; Request.IsAuthenticated은 상태 표시 줄이 다시 렌더링 될 때 formsAuthentication.SignOut() 다음에 계속 true이고 다음 요청까지 상태 표시 줄에 대해 잘못된 마크 업을 다시 렌더링합니다.

Permalinks가 작동해야하므로 Request.IsAuthenticated가 내가이 경우에보고있는 것이므로이 문제를 해결할 방법을 생각할 수 없습니다.

답변

1

나는 내 대답을 찾았습니다. 필자는 현재 응답의 쿠키를 기반으로 현재 요청에 대한 보안 주체를 갱신하는 컨트롤러 확장을 작성했습니다 (이 메서드를 호출하기 전에 권한 부여와 성공적인 호출 후에 설정 됨). 즉시 Request.IsAuthenticated을 업데이트합니다.

참고 : 맞춤식 멤버십을 사용하고 있으므로이 코드는 그대로 사용할 수 없습니다.

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[] {}); 
     } 
    }