【问题标题】:Determine if user can access the requested page?确定用户是否可以访问请求的页面?
【发布时间】:2010-11-18 02:36:38
【问题描述】:

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

我如何获取它,以便向用户显示消息?

【问题讨论】:

    标签: asp.net login security-roles


    【解决方案1】:
    UrlAuthorizationModule.CheckUrlAccessForPrincipal()
    

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

    【讨论】:

    【解决方案2】:

    我最终在登录页面的 page_load 事件中这样做了:

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

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

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

    【讨论】:

    • 这只是部分解决方案,如果您没有可以访问不同页面的不同角色,则最适合。如果这样做,您可以让用户通过身份验证但仍无法访问 ReturnUrl,这可能会导致重定向循环。
    【解决方案3】:

    一种方法是覆盖您的 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;
    }
    

    【讨论】:

      【解决方案4】:

      如果您有不同的目录并且您使用的是 asp.net 身份验证,这很容易。 您只需将 web.config 文件放在每个目录中,并定义可以访问该目录中文件的角色,如下所示:

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

      您可以从 MSDN 上的this 文章中获取更多详细信息

      您可以像这样在主 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>
      

      这是来自this MSDN 上的文章 :)

      编辑:

      在您的页面加载方法中执行以下操作:

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

      希望对您有所帮助!

      【讨论】:

      • 该网站已经按照与您发布的内容类似的方式设置 - 但是,您发布的内容实际上似乎并没有以任何方式回答我的问题。
      • 好的,现在我知道了,使用已通过身份验证但无权查看此页面!我已经编辑了我的答案
      • returnurl 指定的页面上的 page_load 方法没有被触发,因为用户没有达到他们没有被授权的程度。这个概念正是我想要做的。
      • 我一直在Page_Load中使用这个,不知道是否应该在Init中使用。我认为我们需要一些专家建议。
      【解决方案5】:

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

      【讨论】:

      • 我怎么知道他不能访问那个页面呢?我可以确定他是什么角色,但不能确定哪个角色可以访问请求的页面。
      • 嗯,你应该做一些类似关卡的东西。如果您有 4 级以上,您可以访问该页面。或者对于角色,您应该在每个页面上指定一个可以访问该页面的特定角色。
      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        所以你可以这样做:

        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") = "";
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-05
          • 1970-01-01
          • 1970-01-01
          • 2019-07-18
          • 1970-01-01
          • 1970-01-01
          • 2014-08-22
          相关资源
          最近更新 更多