7

我有一个具有多个角色的 ASP.Net 网站,每个角色都可以访问一个单独的目录(即管理员用户可以访问 /admin,购物者可以访问 /shop 等),使用共享登录页面。如果有人访问登录页面,返回 URL 设置为他们无权访问的目录(例如,购物者访问 /login.aspx?returnurl=/admin/index.aspx),则用户可以成功验证(登录凭据为有效),但他们最终回到登录页面(他们无权访问他们请求的页面)。

我该如何选择它,以便向用户显示一条消息?

4

7 回答 7

12
UrlAuthorizationModule.CheckUrlAccessForPrincipal()

是您需要用来测试用户对某个位置(页面或文件夹)的访问权限(http://msdn.microsoft.com/en-us/library/system.web.security.urlauthorizationmodule.checkurlaccessforprincipal.aspx

于 2010-11-17T18:36:38.020 回答
2

我最终在登录页面的 page_load 事件中执行了此操作:

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

想法是,如果经过身份验证的用户最终到达登录页面,他们要么是因为尝试访问他们无权查看的页面而被发送,要么他们已经过身份验证,然后手动进入登录页面(不太可能)。

如果用户已经通过身份验证,则进一步的操作是在用户访问登录页面时将其发送到相关主页。

于 2009-06-26T13:29:38.190 回答
1

如果您有不同的目录并且您正在使用 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";
}

希望这对你有帮助!

于 2009-06-26T11:16:48.130 回答
1

一种方法是覆盖您的 aspx 表单的 OnLoad 并检查是否允许经过身份验证的用户根据角色访问资源。因此,您创建了一个 BasePage.cs(在其中定义了一个继承自 System.Web.UI.Page 的类 BasePage),例如,您的所有表单(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;
}
于 2009-06-26T11:41:05.693 回答
0

您可以在索引页面上重定向他,告诉他他无法访问该页面;)

于 2009-06-26T11:00:04.980 回答
0

那么,你为什么不抓住登录页面中的目录呢?如果登录页面可以确定用户正在尝试访问哪个目录,那么他们可能可以根据角色重定向到正确的页面。如果有人尝试访问 /admin,并且身份验证成功,您可以检查他们是否可以访问那里。如果没有,您可以重定向到基本登录页面,指示他们无权访问,或者将他们重定向到角色的登录页面。

编辑:您可能可以在控件的 LoggedIn 事件中进行重定向。

于 2009-06-26T12:07:57.153 回答
0

另一种选择是在您检查权限时设置会话变量,并将其显示在登录页面上。

所以你可以这样做:

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") = "";
}
于 2009-06-26T13:46:15.660 回答