1

私は本当に奇妙なシナリオを持っています。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."); 
      } 

これは、すべてのブラウザでうまく働いている:私は、私は、ターゲットのページにそれらをリダイレクトし、ユーザーを認証しなAuthCookieを作成し、レスポンスのクッキーにそれを追加しているASP.Net MVC 4のアプリを持っています。私はログインし、私のアプリで安全なページにアクセスすることができます。

私のクライアントはこのアプリのアンドロイド版をリクエストしています。だから、私はこのアプリをAPKファイルに変換する方法を理解しようとしています。私の最初の試みは、アプリケーションを対象とするiframeを持つ単純なindex.htmlページを作成することです。 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を拡張します。

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から派生する必要があります。SecureControllerのコンストラクタで、私は、ユーザーをデシリアライズコードを持っています。権限属性は、メソッドがパイプラインの上位レベルで呼び出される前に実行され、ActionFiltersはさらに実行され、他の属性は実行前に実行されます。

第2に、チケットを復号化し、IPrincipalとIIdentityを設定するコードを表示していません。それが問題のある場所なので、あなたがそれを含めなかったのは奇妙です。

関連する問題