ASP.NET MVC - простой способ временно потребовать авторизацию для всего сайта, кроме одной страницы

Я создаю сайт, состоящий из публичных страниц и страниц, предназначенных только для участников. Система входа в систему и так работает нормально.

Однако я хотел бы запустить закрытый предварительный просмотр, доступный только по приглашению, и временно требовать, чтобы посетители входили в систему для всех действий, кроме страницы приветствия.

В настоящее время у меня есть [Authorize] атрибутов для определенных методов действий. Я мог бы добавить дополнительные атрибуты и к другим методам действий, но это кажется немного взломанным и затруднит их правильное удаление позже, когда я захочу вернуться к более открытому контенту.

Итак, как я могу эффективно добавить требование авторизации для всего сайта? Напомним, я хочу, чтобы единственный /Home/Index маршрут также оставался общедоступным, чтобы люди, которых я пригласил, могли прочитать некоторую информацию, прежде чем активировать свои приглашения.


person Drew Noakes    schedule 18.01.2011    source источник
comment
Возможно, поместите страницу приветствия в другой контроллер, а не на защищенные страницы. Думаю, есть способ потребовать авторизацию для всего контроллера.   -  person CodesInChaos    schedule 19.01.2011
comment
@CodeInChaos, да, это довольно просто. У меня около 20 контроллеров, но это займет меньше времени, чем написание вышеуказанного вопроса :) Я считаю, что также можно зарегистрировать фильтр в моем классе HttpApplication для запуска перед каждым запросом, чтобы я мог возможно, подклассифицируйте атрибут авторизации и закройте замыкание, если это была моя приветственная страница. Тем не менее, я новичок в структуре MVC и хотел бы знать, что лучше всего подходит для такого рода вещей.   -  person Drew Noakes    schedule 19.01.2011
comment
У меня есть сценарий, аналогичный вашему, и я имел большой успех с решением Стива Уиллкока stackoverflow.com/questions/746998/ Я также считаю хорошей идеей наследование всех ваших контроллеров от базового контроллера.   -  person Daniel Liuzzi    schedule 02.02.2011


Ответы (3)


Я думаю, что сделать это в файле web.config было бы лучше всего, поскольку это временно и не требует добавления какого-либо кода C# или использования ролей / имен и т. Д.

Сделайте следующее в своем web.config

<configuration>
      <!-- system.web is the only already in your web.config 
           don't add this, just add the authorization element
           to the existing system.web element -->
  <system.web>
     <authorization>
        <deny users="?"/>
     </authorization>
  </system.web>

  <!-- the login path -->
  <location path="Login/Index">
     <system.web>
        <authorization>
           <allow users="?"/>
        </authorization>
     </system.web>
  </location>

  <!-- welcome page -->
  <location path="Home/Index">
     <system.web>
        <authorization>
           <allow users="?"/>
        </authorization>
     </system.web>
  </location>

  <!-- static files (images, css, js etc.) folder -->
  <location path="Content">
     <system.web>
        <authorization>
           <allow users="?"/>
        </authorization>
     </system.web>
  </location>

</configuration>

Первый элемент <authorization> ограничит доступ к вашему приложению только авторизованным / авторизованным пользователям. Последующие элементы <location> помещают исключения в определенные пути (страница входа, экран приветствия и статические файлы).

Убедитесь, что вы проверили правильность атрибута path для каждого местоположения в зависимости от вашего приложения.

Более подробную информацию об элементе location можно найти на странице MSDN 'location element'.

person Omar    schedule 18.01.2011
comment
Спасибо за это. Мне нравится идея сделать это через config, но, к сожалению, у меня это не работает. Он жалуется, что раздел <authorization> повторяется, цитируя строку в элементе <location> как дубликат. Я пробовал несколько версий этого, но пока еще не заработал. - person Drew Noakes; 19.01.2011
comment
Хммм ... это вызвано тем, что для атрибута path ничего не установлено. Что вы можете сделать, так это разместить приветственную информацию на той же странице, на которой пользователь входит в систему. Это приведет к перенаправлению неавторизованных запросов на страницу входа. - person Omar; 19.01.2011
comment
Я бы предпочел не менять свою страницу входа. И мне пришлось установить для атрибута path значение none, поскольку мой маршрут Home/Index сопоставляется с mysite.com/ (root). Спасибо, в любом случае! - person Drew Noakes; 19.01.2011
comment
Это отлично работает, когда вы используете проверку подлинности Windows в локальной сети. Вы даже можете заблокировать раздел по умолчанию, а затем предоставить более широкий доступ к определенному месту. Также помните, что если вы измените свои таблицы маршрутов, вам придется вернуться и проверить, что пути не были затронуты. - person Lessan Vaezi; 11.07.2011

Добавьте настраиваемый фильтр - вот моя реализация для аналогичного требования. Основное отличие от того, что вы описываете, заключается в том, что для этого требуется установка ролей со страницы приглашения, а не для входа любого вошедшего в систему пользователя.

public class PreviewAuthAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        // if site is live, show page 
        if (Data.Settings.IsLive) return;

        // if request is from localhost or build server, show page
        if (filterContext.HttpContext.Request.IsLocal) return;
        if (filterContext.HttpContext.Request.UserHostAddress.StartsWith("192.168.0")) return;

        // if user has has alpha or admin role, show page
        if (filterContext.HttpContext.Request.IsAuthenticated && (filterContext.HttpContext.User.IsInRole("Alpha") || filterContext.HttpContext.User.IsInRole("Admin"))) return;

        // site is not live and user does not have access - show placeholder

        filterContext.Result = new ViewResult()
        {                
            ViewName="Placeholder",
            ViewData = filterContext.Controller.ViewData,
            TempData = filterContext.Controller.TempData
        };
    }

}
person Tom Clarkson    schedule 18.01.2011
comment
Это выглядит интересно. Могу ли я применить этот атрибут ко всему сайту или мне нужно встроить его в каждый контроллер индивидуально? - person Drew Noakes; 19.01.2011
comment
Я думаю, вы можете настроить его глобально с помощью MVC3, хотя я еще этого не пробовал. Если вы настроите его таким образом, вам также придется добавить код, чтобы исключить страницу входа из фильтрации. Частью моего намерения с этим дизайном было создать что-то, что не будет путаться с обычной авторизацией (которую все еще можно проверить, подключившись с известного IP-адреса), и эффективно удалялось бы, когда сайт запускается, так что это не имеет значения. если атрибуты разбросаны по коду. - person Tom Clarkson; 19.01.2011

Вы можете настроить атрибут Authorize, и в список пользователей частной бета-версии нужно передать некоторую логику. Просто удалите настройку, когда вы сделаете общедоступным.

Ответ на вопрос о том, как настроить атрибут авторизации

Посмотрите ответ, содержащий также AuthorizeOwnerAttribute.

person Greg Levenhagen    schedule 18.01.2011