HAVIT Knowledge Base

Vývoj webových aplikací, .NET, SQL, návrh
Welcome to HAVIT Knowledge Base Sign in | Join | Help
-
Home Články Forums Obrázky Soubory

ASP.NET

Vývoj webových aplikací ASP.NET

web.sitemap - lokalizace a autorizace

Po chvilce bojů a objevení několika bugů se mi nakonec podařilo rozchodit lokalizaci a autorizaci v site-mapách ASP.NET, konkrétně při použití defaultního XmlSiteMapProvider a web.sitemap souborů (částečně to lze ovšem aplikovat i na jiné providery).

Lokalizace website.map

Defaultní XmlSiteMapProvider přímo podporuje lokalizaci web.sitemap souborů, stačí rootovému elementu nastavit atribut enableLocalization="true" a dále se pak na resources můžeme explicitně odkazovat obdobně jako v .aspx souborech, přes výraz $resources:ClassName,KeyName,DefaultValue

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true">
    <siteMapNode title="$resources: Navigation, UvodniStranka" url="~/default.aspx">
    ...
</siteMap>

Výše uvedený příklad by se opíral o soubor ~/App_GlobalResources/Navigation.resx. Jedná se o explicitní způsob lokalizace, existuje ještě implicitní metodika s využitím atributu resourceKey, nicméně implicitní lokalizace jako taková mě neoslovuje, takže ani tentokrát nebudu podorbněji rozvádět.

Pozor také, že mezi dolarem ($) a klíčovým slovem resources nesmí být mezerník. Lokalizovat lze výše uvedeným způsobem atributy title a description, bohužel ne url. Atribut url takto lokalizovat bohužel nelze, ač je to v některých dokumentacích uvedeno.

Pokud bychom chtěli lokalizovat i URL, můžeme to zařídit například tak, že nakonfigurujeme přes web.config dva nezávislé SiteMapProvidery, kde každý bude ukazovat na jiný .sitemap soubor:

<siteMap defaultProvider="CzXmlSiteMapProvider" enabled="true">
  <providers>
    <add name="CzXmlSiteMapProvider"
      description="Provider pro cestinu."
      type="System.Web.XmlSiteMapProvider"
      siteMapFile="WebCz.sitemap"
      securityTrimmingEnabled="true" />
    <add name="EnXmlSiteMapProvider"
      description="Provider pro cestinu."
      type="System.Web.XmlSiteMapProvider"
      siteMapFile="WebEn.sitemap"
      securityTrimmingEnabled="true" />
  </providers>
</siteMap>

...následně bychom podle aktuálního jazyka museli controlu SiteMapDataSource explicitně nastavovat příslušný SiteMapProvider (nastavit property SiteMapDataSource.SiteMapProvider, typ string). Deklaratorně například fíglem:

<asp:SiteMapDataSource
    ID="SiteMapDS"
    SiteMapProvider="<%$ Resources: Navigation, SiteMapProvider %>"
    runat="server"
/>

Viz též obecná lokalizace webových aplikací.

Autorizace - skrývání uživateli nepřístupných položek

XmlSiteMapProvider, přesněji řečeno už bázová třída SiteMapProvider podporuje i authorizaci, resp. skrývání uživateli nedostupných položek. Tato funkčnost je řízena přes property SiteMapProvider.SecurityTrimmingEnabled, která se však nenastavuje programově (má jen get), nýbrž přes konfiguraci provideru z web.config souboru, atributem securityTrimmingEnabled:

<siteMap defaultProvider="MyXmlSiteMapProvider" enabled="true">
    <providers>
        <clear/>
        <add name="MyXmlSiteMapProvider"
         type="System.Web.XmlSiteMapProvider"
         siteMapFile="~/Web.sitemap"
         securityTrimmingEnabled="true" />
    </providers>
</siteMap>

Pokud nastavíme tento atribut, pravděpodobně nám začně funkčnost ihned fungovat. SiteMapProvider si sám hlídá přístupová práva uživatele nastavená přes sekci <authorization /> web.configu a uživateli nepřístupné položky skrývá.

Ovšem pozor!!! Implementace tohoto hlídání není úplně korektní a má problém s authorization pravidly web.config souborů, která se přes <location /> odkazují na podsložky. Chceme-li tedy tuto funkčnost SiteMapProvideru využít, můžeme ve web.config souborech definovat <location /> pravidla pouze pro jednotlivé soubory v příslušné složce a přístupová práva složek jako takových musíme řídit přes samostatné web.config soubory v těchto složkách!!!

Podle dokumentace a schématu .sitemap souboru má existovat u elementu <siteMapNode /> i atribut securityTrimmingEnabled, jakékoliv použití tohoto atributu však vyhazuje výjimku

ConfigurationErrorsException: Unrecognized attribute 'securityTrimmingEnabled'. Note that attribute names are case-sensitive.

Když jsem bádal v kódu XmlSiteMapProvideru, tak tam je tento atribut přímo zakázaný a zřejmě se jedná o nějaký přežitek z beta-verzí.

Element <siteMapNode /> má ještě atribut roles="...", kam lze explicitně nastavit, jakým uživatelským rolím se má node zobrazovat. Pokud však máme dobře nastavené samotné <authorization />, pak to mnohdy nepotřebujeme. Pokud ho přesto nastavíme, pak se vyhodnocuje MÍSTO standardních přístupových práv, nikoliv jako průnik.

Atribut roles="*" (nebo podobně) se nám bude hodit u externích odkazů, jejichž autorizaci nelze jinak vyhodnotit a bez explicitní volby roles se nám odkaz vůbec nezobrazí.

Dále je potřeba si uvědomit, že SiteMapProvider vyhodnocuje přístupová práva od rootu sitemap dolů a pokud nevyhoví nadřazená položka, ustřelí se celý podstrom. Například je tedy problematické bez dalšího použít prázdný atribut url="", protože jeho přístupová práva není jak vyhodnotit a příslušný podstrom se tak nezobrazí - naopak je však možné do url dávat cestu k neexistujícím stránkám, vyhodnocení se provede, jako by existovali. Pokud potřebujeme udělat siteNode bez odkazu, pak musíme použít atribut roles="...", aby bylo přístupová práva jak vyhodnotit.

Související články

Published 5. října 2006 14:29 by Robert Haken

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Orion said:

Hezky :o)

prosince 13, 2006 14:21

What do you think?

(required) 
(optional)
(required) 
Enter the code you see below

Submit