Пользовательский атрибут авторизации не всегда работает - PullRequest
1 голос
/ 07 марта 2012

Я взял код из предыдущего пользовательского атрибута авторизации и получил следующее:

    public class PortalAuthorizeAttribute : AuthorizeAttribute
{
    private WebSiteSession m_UserSession;
    protected WebSiteSession myUserSession
    {
        get
        {
            if (m_UserSession == null)
                try { m_UserSession = (WebSiteSession)HttpContext.Current.Session["UserSession"]; }
                catch
                {
                    m_UserSession = new WebSiteSession();
                    HttpContext.Current.Session["UserSession"] = m_UserSession;
                }
            return m_UserSession;
        }
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.Result is HttpUnauthorizedResult || myUserSession == null || !myUserSession.IsAuthenticated || myUserSession.AdvertiserId == 0)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
            {
                    { "client", filterContext.RouteData.Values["client"] },
                    { "controller", "Account" },
                    { "action", "Login" },
                    { "returnUrl", filterContext.HttpContext.Request.RawUrl }
            });
        }
    }
}

Я работаю из более крупного проекта, поэтому мы получаем наш сеанс из более высокого пространства имен.Проблема будет перенаправлена ​​нормально, если я выйду из системы или если у меня нет авторизации (перенаправление на страницу входа в систему), но кажется, что если я бездействую (время сеанса истекло ??), он все равно будет действовать, как будто я авторизован, но не будуиметь какие-либо учетные данные, прикрепленные к сеансу.Таким образом, он все еще думает, что я действительно вошел в систему, но я не.Я что-то забыл в проверке фильтра?Файл cookie больше не действителен, но, как и пользователь, он все еще может получить доступ к странице.

Спасибо

1 Ответ

1 голос
/ 07 марта 2012

Проблема с вашим кодом связана с тем, что ASP.NET MVC 3 может кэшировать экземпляры фильтров действий. Это одно из критических изменений :

В предыдущих версиях ASP.NET MVC фильтры действий создавались в соответствии с просьба за исключением нескольких случаев. Такое поведение никогда не было гарантировано поведение, а просто деталь реализации и контракт на фильтры должны были считать их безгражданства. В ASP.NET MVC 3 фильтры кешируется более агрессивно. Поэтому любые фильтры пользовательских действий, которые неправильно сохранено состояние экземпляра хранилища.

И поскольку вы кэшировали приватное поле m_UserSession в фильтре действий, оно никогда не становится нулевым, и ваш тест не проходит.

Итак, вот как вы могли бы продолжить:

public class PortalAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var userSession = filterContext.HttpContext.Session["UserSession"] as WebSiteSession;
        if (userSession == null || !userSession.IsAuthenticated || userSession.AdvertiserId == 0)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
            {
                { "client", filterContext.RouteData.Values["client"] },
                { "controller", "Account" },
                { "action", "Login" },
                { "returnUrl", filterContext.HttpContext.Request.RawUrl }
            });
        }
    }
}

Что касается создания и сохранения нового экземпляра WebSiteSession в сеансе, то это не то, что должен делать фильтр авторизации. Это то, что вы должны сделать в своем действии Login после успешной аутентификации. Фильтр авторизации предназначен только для проверки того, авторизован ли пользователь для доступа к действию.

...