Определить, может ли пользователь получить доступ к запрошенной странице?

У меня есть веб-сайт ASP.Net с несколькими ролями, каждая из которых имеет доступ к отдельному каталогу (т.е. пользователи с правами администратора могут получить доступ к / admin, покупатели могут получить доступ к / shop и т. Д.), Используя общую страницу входа. Если кто-то посещает страницу входа с URL-адресом возврата, установленным в каталог, к которому у него нет доступа (например, покупатель посещает /login.aspx?returnurl=/admin/index.aspx), пользователь может успешно пройти аутентификацию (учетные данные для входа действительный), но в конечном итоге они снова попадают на страницу входа (у них нет доступа к запрошенной странице).

Как мне поднять это, чтобы я мог отобразить сообщение, сделанное пользователем?


person user9659    schedule 26.06.2009    source источник


Ответы (7)


UrlAuthorizationModule.CheckUrlAccessForPrincipal()

это то, что вам нужно использовать для проверки доступа пользователей к местоположению (странице или папке) (http://msdn.microsoft.com/en-us/library/system.web.security.urlauthorizationmodule.checkurlaccessforprincipal.aspx)

person Andrey    schedule 17.11.2010
comment
+1. Пример кода доступен по адресу codeproject.com/KB/aspnet/Redirect -To-Login-Popup.aspx. - person Josh Kelley; 14.02.2011

В итоге я сделал это в событии page_load на странице входа:

if (User.Identity.IsAuthenticated)
{
    LoginErrorDetails.Text = "You are not authorized to view the requested page";
}

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

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

person user9659    schedule 26.06.2009
comment
Это только частичное решение, наиболее подходящее, если у вас нет разных ролей, которые могут обращаться к разным страницам. Если вы это сделаете, у вас может быть пользователь, который прошел проверку подлинности, но все еще не может получить доступ к ReturnUrl, что может привести к циклу перенаправления. - person Roman Starkov; 12.06.2013

Один из подходов - переопределить OnLoad ваших aspx-форм и проверить, разрешен ли аутентифицированный пользователь доступ к ресурсу в зависимости от роли. Итак, вы создаете BasePage.cs (в котором вы определяете класс BasePage, который наследуется от System.Web.UI.Page), например, от которого наследуются все ваши формы (aspx), в котором вы делаете следующее:

protected override void OnLoad(EventArgs e)
{
    InitializeSitemap();
    if (SiteMap.CurrentNode != null)
    {
        if (!UrlHelper.IsAnonymousAllowed(SiteMap.CurrentNode) && (!HttpContext.Current.User.Identity.IsAuthenticated || !UrlHelper.IsAccesible(SiteMap.CurrentNode)))
        {
            // You can redirect here to some form that has a custom message
            Response.Redirect("~/Forms/Logout.aspx");

            return;
        }
    }
    base.OnLoad(e);
}

Затем в вашем классе UrlHelper вам понадобится эта функция IsAccessible, используемая выше:

public static bool IsAccesible(SiteMapNode node)
{
    bool toRole = false;

    foreach (string role in node.Roles)
    {
        if (role == "*" || HttpContext.Current.User.IsInRole(role))
        {
            toRole = true;
        }
    }

    return toRole;
}

Вот IsAnonymousAllowed, если вам интересно:

public static bool IsAnonymousAllowed(SiteMapNode node)
{
    return node[AllowAnonymousAttribute] != null ? bool.Parse(node[AllowAnonymousAttribute]) : false;
}
person tzup    schedule 26.06.2009

Если у вас разные каталоги и вы используете аутентификацию asp.net, это очень просто. Все, что вам нужно, это поместить файл web.config в каждый каталог и определить роли, которые могут получать доступ к файлам в этом каталоге, например:

<authorization>
    <allow roles="shoppers"/>
    <deny  users="?"/>
</authorization>

Дополнительную информацию можно получить в этой статье в MSDN.

Вы можете установить все в основном файле web.config следующим образом:

    <!-- Configuration for the "sub1" subdirectory. -->
      <location path="sub1">
        <system.web>
          <httpHandlers>
            <add verb="*" path="sub1" type="Type1"/>
            <add verb="*" path="sub1" type="Type2"/>
          </httpHandlers>
        </system.web>
      </location>

      <!-- Configuration for the "sub1/sub2" subdirectory. -->
      <location path="sub1/sub2">
        <system.web>
          <httpHandlers>
            <add verb="*" path="sub1/sub2" type="Type3"/>
            <add verb="*" path="sub1/sub2" type="Type4"/>
          </httpHandlers>
        </system.web>
      </location>
    </configuration>

Это из этой статьи на MSDN :)

РЕДАКТИРОВАТЬ:

В методе загрузки страницы сделайте следующее:

if(!User.IsInRole("shopper"))
{
    lblNoAccess.Visible=true;
    lnkHome.Url="PATH_TO_HOME_PAGE_OF_THIS_ROLS";
}

Надеюсь, это вам поможет!

person TheVillageIdiot    schedule 26.06.2009
comment
Веб-сайт уже настроен по аналогии с тем, что вы опубликовали, однако то, что вы опубликовали, на самом деле, похоже, никоим образом не отвечает на мой вопрос. - person user9659; 26.06.2009
comment
Хорошо Теперь я понял, пользователь аутентифицирован, но не авторизован для просмотра этой страницы! Я отредактировал свой ответ - person TheVillageIdiot; 26.06.2009
comment
Метод page_load на странице, указанной returnurl, не запускается, так как пользователь не заходит так далеко, как не авторизован. Однако концепция - это именно то, чем я хочу заниматься. - person user9659; 26.06.2009
comment
Я всегда использую это в Page_Load, не знаю, нужно ли его использовать в Init. Я думаю, нам нужен совет экспертов по этому поводу. - person TheVillageIdiot; 27.06.2009

Вы можете перенаправить его на страницу индекса, сообщив ему, что он не может получить доступ к этой странице;)

person Timotei    schedule 26.06.2009
comment
Но как я узнаю, что он не может получить доступ к этой странице? Я могу определить, в какой роли он находится, но не могу определить, какая роль имеет доступ к запрошенной странице. - person user9659; 26.06.2009
comment
Что ж, тебе стоит сделать что-то вроде уровней. Если у вас уровень выше 4, вы можете получить доступ к странице. Или с ролями вы должны назначить на каждой странице определенную роль, которая может получить доступ к этой странице. - person Timotei; 26.06.2009

Ну почему бы вам не поймать каталог на странице входа? Если страница входа в систему может определить, к какому каталогу пользователь пытается получить доступ, возможно, они смогут перенаправить на нужную страницу в зависимости от роли. Если кто-то пытается перейти в / admin и аутентификация проходит успешно, вы можете проверить, есть ли у него доступ к нему. В противном случае вы можете либо перенаправить на базовую целевую страницу, указав, что у них нет доступа, либо перенаправить их на целевую страницу роли.

РЕДАКТИРОВАТЬ: вы, вероятно, могли бы выполнить перенаправление в событии LoggedIn элемента управления.

person johnofcross    schedule 26.06.2009

Еще один вариант - установить переменную сеанса при проверке прав и отобразить ее на странице входа.

Итак, вы могли:

if(!User.IsInRole("shopper"))
{
    session("denied") = "You don't have access to shop";
    response.redirect("/login");
}

Затем на странице входа:

if ( session("denied") != "" ) {
   message.text = session("denied");
   session("denied") = "";
}
person chris    schedule 26.06.2009