1

我有一個非常奇怪的情景,我堅持。我有一個ASP.Net MVC 4應用程序在那裏我認證用戶和創建authCookie並將其添加到響應的Cookie,然後將其重定向到目標頁面:ASP.Net MVC HttpContext.User.Identity正在迷失

  if (ModelState.IsValid) 
      { 
       var userAuthenticated = UserInfo.AuthenticateUser(model.UserName, model.Password); 

       if (userAuthenticated) 
       { 
        var userInfo = UserInfo.FindByUserName(model.UserName); 

        //SERIALIZE AUTHENTICATED USER 
        var serializer = new JavaScriptSerializer(); 
        var serializedUser = serializer.Serialize(userInfo); 
        var ticket = new FormsAuthenticationTicket(1, model.UserName, DateTime.Now, DateTime.Now.AddMinutes(30), false, serializedUser); 
        var hash = FormsAuthentication.Encrypt(ticket); 
        var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash) {Expires = ticket.Expiration}; 

        Response.Cookies.Add(authCookie); 

        if (Url.IsLocalUrl(model.ReturnUrl) && model.ReturnUrl.Length > 1 && model.ReturnUrl.StartsWith("/") && !model.ReturnUrl.StartsWith("//") && !model.ReturnUrl.StartsWith("/\\")) 
        { 
         return Redirect(model.ReturnUrl); 
        } 

        var url = Url.Action("Index", "Course"); 
        return Redirect(url); 
       } 

       ModelState.AddModelError("", "The user name or password provided is incorrect."); 
      } 

這是工作在所有瀏覽器就好了。我可以在我的應用程序中登錄並訪問安全頁面。

我的客戶正在申請此應用的Android版本。所以,我試圖找出如何將這個應用程序轉換成APK文件。我的第一個嘗試是創建一個簡單的index.html頁面,其中包含一個以應用程序爲目標的iframe。這在Firefox和IE 9中運行良好。但是,當訪問包含通過Chrome指向應用程序的iframe的index.html頁面時,我通過上面的登錄代碼並將用戶重定向到安全控制器,但是安全控制器具有自定義屬性,以確保用戶進行身份驗證:

public class RequiresAuthenticationAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.HttpContext.User.Identity.IsAuthenticated) return; 
      if (filterContext.HttpContext.Request.Url == null) return; 

      var returnUrl = filterContext.HttpContext.Request.Url.AbsolutePath; 

      if (!filterContext.HttpContext.Request.Browser.IsMobileDevice) 
      { 
       filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl + string.Format("?ReturnUrl={0}", returnUrl), true); 
      } 
      else 
      { 
       filterContext.HttpContext.Response.Redirect("/Home/Home", true); 
      }   
     } 
    } 

我的應用程序失敗的:filterContext.HttpContext.User.Identity.IsAuthenticated。即使用戶在上面的代碼中進行了身份驗證,IsAuthenticated也始終爲false。

請注意,只有在Chrome中通過iframe訪問應用時纔會發生這種情況。如果我直接訪問應用程序而不是通過iframe,那麼一切正常。

任何想法?

UPDATE:

我的控制器擴展SecureController。在SecureController的構造函數中我有一個反序列化的用戶代碼:

public SecureController() 
     { 
      var context = new HttpContextWrapper(System.Web.HttpContext.Current); 

      if (context.Request.Cookies[FormsAuthentication.FormsCookieName] != null) 
      { 
       var serializer = new JavaScriptSerializer(); 
       var cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName].Value; 
       var ticket = FormsAuthentication.Decrypt(cookie); 
       CurrentUser = serializer.Deserialize<UserInfo>(ticket.UserData); 
      } 
      else 
      { 
       CurrentUser = new UserInfo(); 
      } 


      //if ajax request and session has expired, then force re-login 
      if (context.Request.IsAjaxRequest() && context.Request.IsAuthenticated == false) 
      { 
       context.Response.Clear(); 
       context.Response.StatusCode = 401; 
       context.Response.Flush(); 
      } 
     } 

回答

0

首先,你應該從AuthorizeAttribute,不是ActionFilterAttribute來獲得。授權屬性在該方法甚至在流水線的更高級別被調用之前執行,而ActionFilters執行得更遠,而其他屬性可以在你之前執行。其次,你沒有顯示你用來解密票證和設置IPrincipal和IIdentity的代碼。由於這是問題所在,因此您沒有包含它,這很奇怪。