Меню на основе ролей не работает, что я делаю не так?

Я не могу понять это.

  • У меня есть следующая карта сайта

    <?xml version="1.0" encoding="utf-8" ?>
    
    <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
        <siteMapNode url="~/" title="Root"  description="Go root">
          <siteMapNode url="~/h" title="Home"  description="Go home" />
    
          <siteMapNode url="~/h/uo" title="Ultima Online" description="Ultima Online">        
            <siteMapNode url="~/h/uo/get" roles="RegisteredUser" title="Get account!" description="Get account!" />
          </siteMapNode>
        </siteMapNode>
    </siteMap>
    
    • У меня есть XmlSiteMapProvider с securityTrimmingEnabled="true", который указывает на этот файл карты сайта.

    • Файл, который я хочу обрезать, имеет authorization править в своей папке web.config

      <configuration>
        <system.web>
          <authorization>
            <deny users="?" />
          </authorization>
        </system.web>
      </configuration>
      
    • Файл не может быть доступен через URL, если я наберу http://localhost/h/uo/get Я перенаправлен на страницу входа.

    • Я создал <asp:Menu> вот так в файле главной страницы:

      <asp:SiteMapDataSource ID="MenuSiteMap" ShowStartingNode="false"
                             SiteMapProvider="MenuSiteMapProvider" runat="server" 
      />
      
      <div>
          <asp:Menu ID="NavigationMenu" runat="server" DataSourceID="MenuSiteMap" 
                    CssClass="menu" EnableViewState="false" 
                    IncludeStyleBlock="false" Orientation="Horizontal"
          />
      </div>
      

Тем не менее, когда страница отображается, я вижу Get account узел, который должен быть обрезан, когда я даже не вошел в систему, несмотря ни на что.

  • Что я делаю неправильно?
  • Есть ли какой-либо другой способ построить меню навигации с поддержкой настройки безопасности?

Я использую ASP.NET 4.0 и перезаписываю URL с помощью HttpModule.

1 ответ

Решение

Читая http://forums.asp.net/t/975077.aspx/1 я узнал, что это именно то, что со мной происходит.

Если у узла нет URL-адреса, он ведет себя нормально, но если он есть, как и у всех моих узлов. Обрезка безопасности просто игнорируется.

Я решил свою проблему, прибегнув к более интуитивной реализации карты сайта на основе ролей:

public class TrimmingXmlSiteMapProvider : XmlSiteMapProvider
{
    public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
    {
        if (node.Roles.Cast<string>().Any(r => r == "*"))
            return true;

        if (node.Roles.Count > 0 && node.Roles.Cast<string>().Count(Roles.IsUserInRole) == 0)
            return false;

        return node.ParentNode != null && node.ParentNode.IsAccessibleToUser(context);
    }
}

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

Как это работает?

Сначала я проверяю, является ли какая-либо из ролей, определенных для этого узла, звездочкой, если это так, то я вижу узел.

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

Наконец, я проверяю, есть ли родительский узел, и просто наследую их правило.

Это позволяет обрезать параметры безопасности на самом деле "ОБЕСПЕЧЕНИЕ БЕЗОПАСНОСТИ" и не очень хорошо, однако, черт возьми, он должен работать по умолчанию.

Другие вопросы по тегам