1

私は立ち往生している本当に奇妙なシナリオがあります。ASP.Net MVC 4アプリがあり、ユーザーを認証してauthCookieを作成し、それを応答のCookieに追加してから、ターゲットページにリダイレクトしています。

            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ファイルに変換する方法を理解しようとしています。私の最初の試みは、アプリケーションを対象とするiframeを使用して単純なindex.htmlページを作成することです。これはFirefoxとIE9で問題なく機能します。ただし、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経由ではなく直接アプリにアクセスすると、すべてが正常に機能します。

何か案は?

アップデート:

私のコントローラーは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();
            }
        }
4

1 に答える 1

0

まず、ActionFilterAttribute ではなく、AuthorizeAttribute から派生させる必要があります。承認属性は、パイプラインの上位レベルでメソッドが呼び出される前に実行されますが、ActionFilters はさらに下に実行され、他の属性はユーザーの前に実行できます。

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

于 2012-04-30T15:12:19.353 に答える