Beginning with version 5.1, DotNetNuke introduces provider-based authorization as a first-class framework extension point. Prior to this enhancement, authorization in DotNetNuke took place entirely within the core (generally implemented through classes in the DotNetNuke.Security.Permissions namespace) and was not customizable in any way. Herein we explore the motivations, implementation, and configuration associated with these changes, and discuss what this might mean for future customization.
Authorization, Authentication, and Providers
Prior to delving into the details of authorization in DotNetNuke, it is important to distinguish the often-confused difference between authentication – the binding of an identifier and one or more credentials (e.g., a password) to a principal (e.g., a user) – and authorization, which is the process of verifying that a principal is indeed allowed to perform an action or access a resource. Herein we focus upon this latter function.
Authentication (and, as we shall soon see, authorization) is customizable in the DotNetNuke framework through classes configured via the provider pattern. This pattern allows runtime selection and configuration of a provider so long as that class conforms to the expected interface (or, less frequently, base class) (1). DotNetNuke relies heavily on this pattern to effectuate extendibility for the services (data, membership, navigation, et cetera) upon which it relies.
Why Allow Authorization to Be Extended?
Before we touch on the details associated with the abstraction of authorization in the DotNetNuke framework, it is worth exploring why such a change would be made. For the DotNetNuke Corporation, the answer is simple: granular permissions are one of the differentiating factors planned between the Professional and Community Editions (2). Consumers of the former will be able to assign permissions at the very detailed level required by many enterprise customers (to whom that edition is targeted), while Community Edition deployments will continue to benefit from the (robust) level of authorization that has always been available on the platform.
But, just as the DotNetNuke Corporation will leverage this extension point for its enterprise customers, so too may any developer. This will ultimately allow both for third-party extensions to accommodate common advanced scenarios, and custom development for specific one-off situations. This enhancement is an improvement for all involved.
This will ultimately allow both for third-party extensions to accommodate common advanced scenarios, and custom development for specific one-off situations
In addition to the benefits described above, the consolidation of authorization services into a single, dedicated class allows for a reduced security surface area and thereby serves to increase overall framework security. Whereas in the past there might have been several places to attack authorization logic, this functionality will now be consolidated into a single-purpose assembly dedicated to one task.
Authorization Prior to Version 5.1
Having discussed the reasons why authorization was abstracted, we now examine the state of authorization in DotNetNuke prior to version 5.1. Before this version, authorization logic was internal to the framework (located in the DotNetNuke.Security.Permissions namespace) and not extendable or customizable by developers in any way (save for a draconian recompilation of the entire core framework). For example, module permission-related logic was contained within the ModulePermissionController class, while file-based authorization was handled entirely by the FilePermissionController. The methods in these classes were static, not virtual, and not customizable in any manner, as is demonstrated in the ModulePermissionController.HasModulePermission method detailed in listing 1.
Public Class ModulePermissionController
...
Public Shared Function HasModulePermission(...) As Boolean
Return PortalSecurity.IsInRoles(...)
End Function
...
End Class
Listing 1: Pre-5.1 implementation of ModulePermissionController.HasModulePermission (simplified for reading). This method is static and not customizable without modifying the core DotNetNuke framework.
While it does perhaps make some sense for these authorizations to be performed by those controller classes that utilize the functionality, this approach makes it difficult to adjust, extend, and refine the framework for novel or unforeseen design requirements. Decoupling policy-enforcement functionality from its authorization-related counterpart does have some attractive design characteristics, including cleaner overall separation of concern.
Authorization in DotNetNuke 5.1
Authorization services in version 5.1 have been abstracted into a separate provider assembly and the relevant functionality has been moved therein. The out-of-the-box provider included with the Community Edition is defined as DotNetNuke.Security.Permissions.CorePermissionProvider. The class diagram in figure 1 depicts the relationship of this class to the core framework.

Fig. 1: Class diagram demonstrating the relationship between the core framework controller classes, the PermissionProvider class, and the concrete CorePermissionProvider authorization implementation.
Unlike many other DotNetNuke providers, the permission provider is not interface-driven, and must currently be inherited from DotNetNuke.Security.Permissions.PermissionProvider (though as of press time this version was still in beta and the final architecture remains subject to change). This is somewhat unfortunate as it potentially complicates some testing patterns (in particular the ability to easily mock a custom provider), but may nonetheless be generally worked around to meet most design goals.
Like all the other DotNetNuke providers (e.g., data, membership, profile), the permission provider is configured in the web.config. The default configuration is presented in listing 2. Any custom provider would require a new entry under the <providers> node with the desired type (and the containing assembly must be deployed into the application’s bin directory).
<configuration>
...
<dotnetnuke>
...
<permissions defaultProvider="CorePermissionProvider">
<providers>
...
<add name="CorePermissionProvider"
type="DotNetNuke.Security.Permissions.
CorePermissionProvider..."
providerPath="..." />
</providers>
</permissions>
</dotnetnuke>
</configuration>
Listing 2: Default web.config Configuration for the 5.1 Permission Provider (with extraneous details omitted)
The existing classes that utilized previously-internal permission functionality have been modified to operate against the new provider. For example, the TabPermissionController was modified to route authorization to the provider instance via a provider.HasTabPermission call (listing 3). The provider itself has assumed the functionality previously implemented directly in the TabPermissionController class, an example of which is shown in listing 4.
Public Shared Function HasTabPermission(...) As Boolean
Dim hasPermission As Boolean = Null.NullBoolean
If permissionKey.Contains(",") Then
For Each permission As String In permissionKey.Split(",")
If provider.HasTabPermission(objTabPermissions,_
permission) Then
hasPermission = True
Exit For
End If
Next
Else
hasPermission = provider.HasTabPermission_
(objTabPermissions, permissionKey)
End If
Return hasPermission
End Function
Listing 3: TabPermissionController.HasTabPermission modified in version 5.1 to utilize the new permission provider. Note that this method routes all authorization decisions to the provider (accessed through a private field named “provider”).
Public Overridable Function HasTabPermission(...) As Boolean
Return PortalSecurity.IsInRoles(...)
End Function
Listing 4: The HasTabPermission method of the default Community Edition permission provider class, which has subsumed the functionality that was previously internal to the core.
The DotNetNuke 5.1 Permission Provider Implementation
The DotNetNuke 5.1 authorization provider may be generally subdivided into three classes of authorization: folder permissions, module-related permissions, and page-related permissions. Each of these groups contains a number of overridable methods as outlined in table 1. These methods generally indicate whether a user may perform a particular action (e.g., CanDeleteModule returns a Boolean indicating whether a user may delete a particular module instance), with a few exceptions that update, delete, or apply to collections of permission objects.
| Category |
Overridable Methods |
| Module Permissions |
CanAdminModule |
| CanDeleteModule |
| CanEditModuleContent |
| CanExportModule |
| CanImportModule |
| CanManageModule |
| CanViewModule |
| DeleteModulePermissionsByUser |
| GetModulePermissions |
| HasModulePermission |
| Page Permissions |
CanAddContentToPage< |
| CanAddPage |
| CanAdminPage |
| CanCopyPage |
| CanDeletePage |
| CanExportPage |
| CanImportPage |
| CanManagePage |
| CanNavigateToPage |
| CanViewPage |
| DeleteTabPermissionsByUser |
| Folder Permissions |
CanAdminFolder |
| CanAddFolder |
| CanCopyFolder |
| CanDeleteFolder |
| CanManageFolder |
| CanViewFolder |
| DeleteFolderPermissionsByUser |
| GetFolderPermissionsCollectionByFolder |
| HasFolderPermission |
| SaveFolderPermissions |
Table 1: Methods available in the DotNetNuke 5.1 permission provider
While an understanding of how the core framework performs authorization is important for those who wish to better-understand how DotNetNuke works, it is worth mentioning that a module developer typically will not utilize this provider directly. Instead, modules should continue to use the methods exposed by the relevant controller (e.g., TabController.HasTabPermission). The information presented herein is especially important, however, for those who wish to extend or augment authorization services.
Extending Authorization Services
Developers who wish to extend or enhance the built-in DotNetNuke authorization services will likely do so via simple inheritance (when base functionality is largely sufficient), decoration (for runtime flexibility in authorization functionality), or adaptation (to allow a foreign authentication system to be used within the DotNetNuke framework). In many cases some combination of these design patterns might be selected for advanced integration requirements.
The ability to extend DotNetNuke using authorization as a first-class extension point allows for a number of interesting possibilities. For example, the page-related authorization methods may be utilized to allow users belonging to one portal to be able to edit the pages on another. In addition to these obvious direct permission manipulations, more esoteric enhancements might include STS federated authorization using the new Microsoft Geneva framework or even the enabling of Amazon S3 as a backing store for files (although authorization would only be one piece of this particular puzzle).
The Bottom Line
The decision to offer authorization services as a first-class extension point on the DotNetNuke platform is an important step forward, and allows for customization that is sure to be filled by third-party extensions to cover novel requirements. For developers, an appreciation of how this provider is implemented, utilized, and configured is an important part of understanding the framework as a whole.
For developers, an appreciation of how this provider is implemented, utilized, and configured is an important part of understanding the framework as a whole
References
- Howard, R. Provider Model Design Pattern and Specification. Microsoft Developer Network. [Online] March 4, 2004. [Cited: May 24, 2009.]; http://msdn.microsoft.com/en-us/library/ms972319.aspx.
- Willhite, S. RE: Granular Permissions Stripped from DNN5 Community Edition? DotNetNuke. [Online] April 30, 2009. [Cited: May 24, 2009.];
http://www.dotnetnuke.com/Default.aspx?ThreadId=305055&Scope=Posts&TabId=795.