# Wednesday, November 23, 2005

It seems like forever ago that I started recommending Fredrik Normen's Permission Manager.  Recently I was tasked to find a way to restrict nodes in a SiteMap based on Permission.  Today I completed that task and thought I would share it with the world.  First of all, I appoligize for writing the code in VB.NET (employers standard), but you can all compile it and reference it from C# so get over it.

What I did to create the PermissionXmlSiteMapProvider was to inherit directly from XmlSiteMapProvider and then extend 2 methods.  First of all I extended the Initialize method so that I could verify that it was configured properly.  Since it is dependent on the presence of Permission Manager and it properly working I added a simple check to verify that it has a provider.

The second method to override for the addtion of Permission to a SiteNode was IsAccessibleToUser.  Thankfully the siteNode can have extra attributes on it without complaint.  I used that to check for the permission attribute.  If it is there then a call to Permission Manager is done for the named permission and the currently logged in user.

After configuring my applications to use my new Provider I restrict access to nodes as easy as this:

<siteMapNode url="Edit.aspx" title="Edit" permission="Modify" />

Since I built on top of the XmlSiteMapProvider I also get the ability to do Roles restriction and a combination of Roles and permission:

<siteMapNode url="Delete.aspx" title="Delete" Roles="Admins, Editors" permission="Delete" />

It is important to note a few things that I ran into while working on this solution.  You must enable Security Trimming.  If you will restrict based on Roles you also must enable RoleManager.  Restricting via Roles is a little quirky as described in the MSDN Site Map Providers document.  Specifically review the Security Trimming section.

Here is the siteMap section of Web.config that implements the PermssionXmlSiteMapProvider:

<siteMap enabled="true" defaultProvider="PersmissionXmlSiteMapProvider">
  <
providers>
    <
add name="PersmissionXmlSiteMapProvider
           
type="IDCL.Web.Security.PersmissionXmlSiteMapProvider, IDCL.Web"
           
description="Permission xml site map provider"
          
securityTrimmingEnabled="true"
          
siteMapFile="Web.sitemap"/>
  providers>
siteMap>

Obviously you also need to have Permission Manager installed and configured or this will not work.

Here is the code for the provider:

Imports System
Imports System.Web
Imports System.Configuration.Provider
Imports System.Web.Configuration
Imports Nsquared2.Security

Public Class PersmissionXmlSiteMapProvider
Inherits XmlSiteMapProvider

Public Overrides Sub Initialize(ByVal name As String, ByVal config As System.Collections.Specialized.NameValueCollection)

' Verify that config isn't null
If config Is Nothing Then
  Throw New ArgumentNullException("config")
End If

' Verify that Permission Manager is configured
If PermissionManager.Provider Is Nothing Then
  Throw New ProviderException("Permission Manager default provider missing.")
End If

' Add a default "description" attribute to config if the
' attribute doesn't exist or is empty
If String.IsNullOrEmpty(config("description")) Then
  config.Remove("description")
  config.Add(
"description", "PermissionXmlSiteMap provider")
End If

' Call the base class's Initialize method
MyBase.Initialize(name, config)
End Sub

Public Overrides Function IsAccessibleToUser(ByVal context As System.Web.HttpContext, ByVal node As System.Web.SiteMapNode) As Boolean

  Dim authorized As Boolean = MyBase.IsAccessibleToUser(context, node)

  'Pull the permission out of the sitemap node as an attribute
  Dim Permission As String = node.Item("permission")
  If Not Permission Is Nothing And authorized Then
    If context.User.Identity.IsAuthenticated Then
      ' Only check permission for known users
      Return PermissionManager.HasUserPermission(context.User.Identity.Name, Permission)
    Else
      ' The presence of a permission requires a known user
      Return False
    End If
  End If

Return authorized

End Function
End
Class

The PermissionSiteMapProvider.zip file with this article includes the Provider solution and a sample web.config

Wednesday, November 23, 2005 4:27:33 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, November 22, 2005
I love my Zen Micro.  Tiger Direct has one now for $129.99 after rebate.  Get one of these and then sign up for Yahoo Music Unlimited for a year while the price is still only $59.88.  You won't be disappointed!
Tuesday, November 22, 2005 8:13:31 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, November 10, 2005

Today I discovered that Microsoft is answering the community rant against losing web projects in VS 2005.  They have introduced Web Deployment Projects as an add-in for VS 2005.  They have essentially wrapped MS Build into a project type for the web.  Most exciting is that they did us right and took it beyond just providing a way to do exclusions and assembly naming.  My favorite new thing is the ability to do configuration management as part of the build process.  I can now have multiple configuration documents that target different deployment options.  Thank you ScottGu and the ASP.NET team!  This is exactly the kind of thing that we needed!

Thursday, November 10, 2005 10:02:31 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, November 07, 2005

Today is the official launch date for Microsoft Visual Studio 2005 and SQL 2005.  The team at DotNetNuke surprised us all be releasing their newest builds today as well.  Most surprising was the 4.0 release which runs on the .NET 2.0 framework.  I hadn't expected that for a few months still, but I am thrilled to see it.  I will be pushing hard at the office now to move from Beta 2 to the final release of .NET 2.0 so that we can run DNN 4.0 and begin building ASP.NET 2.0 modules.  Thanks DNN crew for your relentless efforts on this product.

Monday, November 07, 2005 11:32:53 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |