Определить, может ли пользователь получить доступ к запрашиваемой странице? - PullRequest
7 голосов
/ 26 июня 2009

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

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

Ответы [ 7 ]

12 голосов
/ 17 ноября 2010
UrlAuthorizationModule.CheckUrlAccessForPrincipal()

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

2 голосов
/ 26 июня 2009

Я закончил тем, что сделал это в событии page_load на странице входа в систему:

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

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

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

1 голос
/ 26 июня 2009

Один из подходов - переопределить 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;
}
1 голос
/ 26 июня 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:)

EDIT:

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

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

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

0 голосов
/ 26 июня 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") = "";
}
0 голосов
/ 26 июня 2009

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

EDIT: Возможно, вы могли бы выполнить перенаправление в событии LoggedIn элемента управления.

0 голосов
/ 26 июня 2009

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

...