2

AuthorizeAttributeを使用して、ユーザーがページにアクセスするために18歳以上のCookieが設定されていることを確認しています。

これは問題なく動作しますが、私は今少し拡張しています。すべてのビューがこの属性を使用するため、サイトを早期に起動できるようにするために使用しています。add?VIEWSITE = trueを任意のURLに使用すると、Session変数が設定され、サイトへのアクセスが許可されます。それ以外の場合は、保留ページに移動します。

これは、ページを初めて実行するときに正常に機能します。しかし、私はページで出力キャッシュを使用しています、そして次にページがロードされるとき、私のhttpcontext.sessionはnullですか?

属性が正しい順序で実行されるように、属性に「順序」変数を追加しました。

    [OfAge(Order = 1)]
    [OutputCache(Order = 2, Duration = 2000, VaryByParam = "categoryName")]

私の属性からのスニピット:

        protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        HttpRequestBase req = httpContext.Request;
        HttpResponseBase res = httpContext.Response;


        DateTime Live_Date = new DateTime(2011, 07, 01, 07, 0, 0);

        if (DateTime.Now > Live_Date || req.QueryString["VIEWSITE"] != null || httpContext.Session["VIEWSITE"] != null)
        {
            httpContext.Session["VIEWSITE"] = true;

ページがキャッシュからロードされた後、セッション変数を読み取ったり設定したりできるようにするために、ここで欠けているものはありますか?

明確にするために、nullであるのはhttpContext.Sessionであり、具体的にはhttpContext.Session["VIEWSITE"]ではありません。

4

1 に答える 1

1

3年後、私は同様の問題に遭遇しました。今私は専門家ではありませんが、各コントローラーコンテキスト呼び出しは独自の空間で一意であると信じているため、新しい呼び出しでは httpContext.Session は null になります。

私の問題は、セッション変数に (彼のカスタム アプリケーション権限で) 保存したい、ログインした AD ユーザーの形で発生しました。AuthorizationAttribute も拡張していますが、このフィルターをコントローラー アクションに適用すると、ユーザーが保存されていても httpContext が null になります。

同じ問題と戦っている人々の場合、これを回避する方法は、このユーザーとそのセッション状態が他のコントローラー全体で保持されるベースコントローラーを作成することです (ベースコントローラーを継承します)。

元。

私のモデル:

public class LoggedInUser
    {
        public somenamespace.userclass UserProfile { get; set; }
        public List<somenamespace.user_permission_class> UserPermissions { get; set; }
    }

私のベースコントローラー:

public class ControllerBase : Controller
    {
        private LoggedInUser _LoginUser;

        public LoggedInUser LoginUser
        {
            get 
            {
                if (_LoginUser != null)
                    return _LoginUser;

                if (Session["_LoginUser"] == null)
                    return null;

                return Session["_LoginUser"] as LoggedInUser;
            }
            set
            {
                _LoginUser = value;
                Session["_LoginUser"] = _LoginUser;
            }
        }

        public void PerformUserSetup(string sUsername) // sUsername for testing another user, otherwise User.Identity will be used.
        {
            sUsername = string.IsNullOrEmpty(sUsername) ? User.Identity.Name : sUsername;
            sUsername = (sUsername.IndexOf("\\") > 0) ? sUsername.Split('\\').ToArray()[1] : sUsername;

            // Todo - SQL conversion to stored procedure
            List<userclass> tmpUser = Root.Query<userclass>(/*sql to select user*/).ToList();

            List<user_permission_class> tmpUserpermissions = Root.Query<user_permission_class>(/*sql to select user permissions*/).ToList();

            LoggedInUser _LoginUser = new LoggedInUser();
            _LoginUser.UserProfile = tmpUser.First();
            _LoginUser.UserPermissions = tmpUserpermissions;

            LoginUser = _LoginUser;
        }

    }

私のHomeController(MVCの例の標準):

public class HomeController : ControllerBase
    {
        [Authorize] // Standard AuthorizeAttribute (AD test)
        public ActionResult Index()
        {
            if (Session["_LoginUser"] == null)
                PerformUserSetup("");

            return View();
        }
    }

他のコントローラーアクションで使用するカスタムパーミッションチェックフィルター:

public class PermissionAuthorize : AuthorizeAttribute
    {
        private readonly string[] permissions;
        public PermissionAuthorize(params string[] perms)
        {
            this.permissions = perms;
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool auth = false;

            if (httpContext.Session["_LoginUser"] == null)
            {
                // Do nothing as auth is false.
            }
            else
            {
                // Check permissions and set auth = true if permission is valid.
                auth = true;
            }

            return auth;
        }

        /* not using
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var tmp = filterContext.HttpContext.Session;
        }
        */
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // Todo - direct to "unauth page"
            base.HandleUnauthorizedRequest(filterContext);
        }
    }

使用法:

public class Some_OtherController : /*PossibleNamespace?.*/ControllerBase
    {

        [PermissionAuthorize("somepermission")] // This was a CRUD application thus 1 permission per actionresult
        public ActionResult ViewWhatever()
        {
            ....
        }
    }
于 2014-11-13T14:28:01.860 に答える