Filtering Web Parts


When building a Web Part application, you might want to allow different users of the application to see different sets of Web Parts. For example, you might want the president of the company to be able to view the World Domination Plans Web Part, but you wouldn't want a lowly temporary employee to see the contents of this particular Web Part. On the other hand, you might want everyone in the company to be able to see the Copying Machine Locations Web Part.

You can filter the Web Parts that a user can see on a Web Part page. When you create an authorization filter, only the Web Parts that a person is authorized to view will appear in Web Part Zones and Web Part Catalogs.

You can create an authorization filter in either of two ways. First, you can handle the AuthorizeWebPart event of the WebPartManager control class. This event is raised every time that a Web Part is added to the page while the Web Part Framework builds the page. The event argument passed to the event handler for the AuthorizeWebPart event includes an IsAuthorized property. You can set this property to the value TRue or False to indicate whether a Web Part is authorized to be displayed.

You can also create an authorization filter by creating a custom WebPartManager control that inherits from the WebPartManager control and overrides its IsAuthorized() method. The IsAuthorized() method returns a Boolean value. If you return the value False, then a Web Part fails authorization and it is not added to the page. Using this second way of creating an authorization filter makes sense when you want to apply the same authorization logic to multiple Web Part pages in an application.

Regardless of whether you handle the AuthorizeWebPart event or you override the IsAuthorized() method, it is up to you to write the logic for the authorization filter. In the following sections, you'll learn three ways of filtering Web Parts, depending on the role of the user.

Filtering by Authorization Filter

One of the core properties shared by every Web Part is the AuthorizationFilter property. This property represents a string that you can use when filtering Web Parts. You can assign any string value to this property.

For example, you can use the AuthorizationFilter property to represent a user role. In that case, in your AuthorizeWebPart event handler, you can prevent users who are not in the correct role from seeing a Web Part.

In this section, we create three Web Parts: the MissionStatementPart, the CopyingMachinesLocationPart, and the WorldDominationPlanPart. These Web Parts are contained in Listings 28.12, 13, and 14.

Listing 28.12. MissionStatementPart.ascx

<%@ Control Language="VB" ClassName="MissionStatementPart" %> <h3>Mission Statement</h3> The purpose of this company is...

Listing 28.13. CopyingMachinesLocationPart.ascx

<%@ Control Language="VB" ClassName="CopyingMachinesLocationPart" %> <h3>Copying Machines Location</h3> The copying machines are located on the 5th floor...

Listing 28.14. WorldDominationPlansPart.ascx

<%@ Control Language="VB" ClassName="WorldDominationPlansPart" %> <h3>World Domination Plans</h3> Start by placing secret messages in every Unleashed book...

Notice that there is nothing special about these Web Parts. They are simply User controls.

Next, because the Web Parts are filtered by user role, roles need to be enabled for the application. One option would be to use Windows Authentication and local Windows groups. This is the default type of authentication enabled for an ASP.NET application and there is nothing wrong with this option. However, this sample uses Forms Authentication and custom roles. It is easier to switch between users when using Forms Authentication, which makes it easier to test the page.

Forms Authentication and custom roles can be enabled with the Web configuration file in Listing 28.15.

Listing 28.15. Web.Config

<?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">     <system.web>       <authentication mode="Forms" />       <roleManager enabled="true" />       <membership defaultProvider="MyMembershipProvider">       <providers>       <add name="MyMembershipProvider"         type="System.Web.Security.SqlMembershipProvider"         connectionStringName="LocalSqlServer"         requiresQuestionAndAnswer="false"         minRequiredNonalphanumericCharacters="0"         minRequiredPasswordLength="1"         requiresUniqueEmail="false" />       </providers>       </membership>     </system.web> </configuration>

CD Note

The configuration file in Listing 28.15 is included on the CD with the name Web.Config_Disabled so that the configuration file doesn't interfere with the other samples in this chapter.


The web configuration file in Listing 28.15 enables Forms Authentication and the Role Manager. It also configures the Membership provider so that email addresses and strong passwords are not required when creating a new user. (This makes it easier to create new users in the page.)

Finally, the page in Listing 28.16 uses an authorization filter to display the three Web Parts (see Figure 28.6).

Figure 28.6. Filtering Web Parts.


Listing 28.16. ShowAuthorizationFilter.aspx

[View full width]

<%@ Page Language="VB" %> <%@ Register TagPrefix="user" TagName="MissionStatementPart"   src="/books/3/444/1/html/2/~/MissionStatementPart.ascx" %> <%@ Register TagPrefix="user" TagName="WorldDominationPlansPart"   src="/books/3/444/1/html/2/~/WorldDominationPlansPart.ascx" %> <%@ Register TagPrefix="user" TagName="CopyingMachineLocationsPart"   src="/books/3/444/1/html/2/~/CopyingMachinesLocationPart.ascx" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server">     ''' <summary>     ''' Create the Administrator and Serf roles and     ''' create two users named Bill and Tom.     ''' </summary>     Private  Sub Page_Load()         If Not Roles.RoleExists("Administrator") Then             Roles.CreateRole("Administrator")             Roles.CreateRole("Serf")             Membership.CreateUser("Bill", "secret")             Membership.CreateUser("Tom", "secret")             Roles.AddUserToRoles("Bill", New String(){"Administrator", "Serf"})             Roles.AddUserToRole("Tom", "Serf")         End If     End Sub     ''' <summary>     ''' Only add a Web Part when the AuthorizationFilter     ''' property contains the current user's role or the     ''' AuthorizationFilter property is empty.     ''' </summary>     Protected Sub WebPartManager1_AuthorizeWebPart(ByVal sender As Object, ByVal e As  WebPartAuthorizationEventArgs)         e.IsAuthorized = User.IsInRole(e.AuthorizationFilter) Or e.AuthorizationFilter =  String.Empty     End Sub     ''' <summary>     ''' Hide the menu for unauthorized users     ''' </summary>     Private  Sub Page_PreRender()         Menu1.Visible = Request.IsAuthenticated     End Sub     Protected  Sub Menu1_MenuItemClick(ByVal sender As Object, ByVal e As MenuEventArgs)         WebPartManager1.DisplayMode = WebPartManager1.DisplayModes(e.Item.Text)     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <style type="text/css">         .login         {             border:solid 1px black;             background-color:white;         }         .column         {             float:left;             width:30%;             height:200px;             margin-right:10px;             border:solid 1px black;             background-color: white;         }         .menu         {             margin:5px 0px;         }         html         {             background-color:#eeeeee;         }     </style>     <title>Show Authorization Filter</title> </head> <body>     <form  runat="server">     <asp:WebPartManager                  OnAuthorizeWebPart="WebPartManager1_AuthorizeWebPart"         Runat="server" />     <asp:Login                  Css         TitleText=""         Orientation="horizontal"         DisplayRememberMe="false"         Runat="server" />     <asp:Menu                  OnMenuItemClick="Menu1_MenuItemClick"         Orientation="Horizontal"         Css         Runat="server">         <Items>         <asp:MenuItem Text="Browse" />         <asp:MenuItem Text="Design" />         <asp:MenuItem Text="Catalog" />         </Items>     </asp:Menu>     <asp:WebPartZone                  Css         Runat="server">         <ZoneTemplate>         <user:MissionStatementPart                          title="Mission Statement"             runat="server" />         <user:CopyingMachineLocationsPart                          title="Copying Machine Locations"             AuthorizationFilter="Serf"             runat="server" />         <user:WorldDominationPlansPart                          title="World Domination Plans"             AuthorizationFilter="Administrator"             runat="server" />         </ZoneTemplate>     </asp:WebPartZone>     <asp:WebPartZone                  Css         Runat="server" />     <asp:CatalogZone                  Css         Runat="server">         <ZoneTemplate>         <asp:DeclarativeCatalogPart                          Runat="server">             <WebPartsTemplate>             <user:CopyingMachineLocationsPart                                  title="Copying Machine Locations"                 AuthorizationFilter="Serf"                 runat="server" />             <user:WorldDominationPlansPart                                  title="World Domination Plans"                 AuthorizationFilter="Administrator"                 runat="server" />             </WebPartsTemplate>         </asp:DeclarativeCatalogPart>         <asp:PageCatalogPart                          Runat="server" />         </ZoneTemplate>     </asp:CatalogZone>     </form> </body> </html>

The Page_Load() method in Listing 28.16 automatically creates two roles named Administrator and Serf. The method also creates two users named Bill and Tom. Bill is associated with both the Administrator and Serf role and Tom is associated with the Serf role.

After you open the page in Listing 28.16, you'll see only the MissionStatementPart Web Part because this is the only Web Part that anonymous users can view.

If you log in with the username Tom and password secret, then you can see both the MissionStatementPart and CopyingMachineLocationsPart Web Parts. Both these Web Parts are visible in both the Web Part Zone and Catalog Zone contained in the page.

Finally, if you log in with the username Bill and the password secret, you can see all three Web Parts. All three Web Parts are displayed in both the Web Part Zone and the Catalog Zone.

Notice that the CopyingMachinesLocationPart and WorldDominationPlansPart Web Parts are declared with an AuthorizationFilter attribute. The CopyingMachinesLocationPart is associated with the Serf user role. The WorldDominiationPlansPart is associated with the Administrator user role.

The WebPartManager control has an AuthorizeWebPart event handler associated with it. The event handler consists of the following line of code:

e.IsAuthorized = User.IsInRole(e.AuthorizationFilter) Or e.AuthorizationFilter = String.Empty


This line of code checks whether the current user is a member of the role represented by a Web Part's AuthorizationFilter property. If the user is in the role associated with the Web Part or the Web Part has no role associated with it, then the user is authorized to see the Web Part.

Filtering by User Control Path

Using the AuthorizationFilter property is potentially dangerous when you use the property with Generic Web Parts. The problem is that you might forget to add the AuthorizationFilter attribute when adding a Generic Web Part to a zone. Because the AuthorizationFilter property is not a member of the IWebPart interface, you cannot set this property in the User Control itself.

This section explores an alternate method of creating an authorization filter. This method works only with Web Parts created as User Controls. Web Parts will be filtered depending on their paths.

The idea is that to place every Web Part that a member of the Administrator role can see in a folder named Administrator. Furthermore, every Web Part that a member of the Serf role can see will be located in a folder named Serf.

Let's start by creating the two User Controls contained in Listing 28.17 and 18.

Listing 28.17. Serf\SerfPart.ascx

<%@ Control Language="VB" ClassName="SerfPart" %> <h3>Serf Part</h3>

Listing 28.18. Administrator\AdministratorPart.ascx

<%@ Control Language="VB" ClassName="AdministratorPart" %> <h3>Administrator Part</h3>

The SerfPart Web Part is located in the Serf folder and the AdministratorPart Web Part is located in the Administrator folder.

The page in Listing 28.19 filters the two Web Parts. Different Web Parts are displayed, depending on the role of the current user.

Listing 28.19. ShowAuthorizationPath.aspx

[View full width]

<%@ Page Language="VB" %> <%@ Register TagPrefix="user" TagName="AdministratorPart"  src="/books/3/444/1/html/2/~/Administrator/AdministratorPart.ascx" %> <%@ Register TagPrefix="user" TagName="SerfPart" src="/books/3/444/1/html/2/~/Serf/SerfPart.ascx" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server">     ''' <summary>     ''' Create the Administrator and Serf roles and     ''' the Bill and Tom user accounts     ''' </summary>     Private  Sub Page_Load()         If Not Roles.RoleExists("Administrator") Then             Roles.CreateRole("Administrator")             Roles.CreateRole("Serf")             Membership.CreateUser("Bill", "secret")             Membership.CreateUser("Tom", "secret")             Roles.AddUserToRoles("Bill", New String(){"Administrator", "Serf"})             Roles.AddUserToRole("Tom", "Serf")         End If     End Sub     ''' <summary>     ''' Filter based on the Web Part User Control path     ''' </summary>     Protected  Sub WebPartManager1_AuthorizeWebPart(ByVal sender As Object, ByVal e As  WebPartAuthorizationEventArgs)         e.IsAuthorized = User.IsInRole(GetFolder(e.Path))     End Sub     ''' <summary>     ''' Gets the name of the folder that contains     ''' the User Control     ''' </summary>     Private Function GetFolder(ByVal path As String) As String         Dim baseFolder As String = String.Empty         Dim parts As String() = path.Split("/"c)         If parts.Length > 2 Then             baseFolder = parts(1)         End If         Return baseFolder     End Function     Private  Sub Page_PreRender()         Menu1.Visible = Request.IsAuthenticated     End Sub     Protected  Sub Menu1_MenuItemClick(ByVal sender As Object, ByVal e As MenuEventArgs)         WebPartManager1.DisplayMode = WebPartManager1.DisplayModes(e.Item.Text)     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <style type="text/css">         .login         {             border:solid 1px black;             background-color:white;         }         .column         {             float:left;             width:30%;             height:200px;             margin-right:10px;             border:solid 1px black;             background-color: white;         }         .menu         {             margin:5px 0px;         }         html         {             background-color:#eeeeee;         }     </style>     <title>Show Authorization Path</title> </head> <body>     <form  runat="server">     <asp:WebPartManager                  OnAuthorizeWebPart="WebPartManager1_AuthorizeWebPart"         Runat="server" />     <asp:Login                  Css         TitleText=""         Orientation="horizontal"         DisplayRememberMe="false"         Runat="server" />     <asp:Menu                  OnMenuItemClick="Menu1_MenuItemClick"         Orientation="Horizontal"         Css         Runat="server">         <Items>         <asp:MenuItem Text="Browse" />         <asp:MenuItem Text="Design" />         <asp:MenuItem Text="Catalog" />         </Items>     </asp:Menu>     <asp:WebPartZone                  Css         Runat="server">         <ZoneTemplate>         <user:AdministratorPart                          title="Administrator Part"             runat="server" />         <user:SerfPart                          title="Serf Part"             runat="server" />         </ZoneTemplate>     </asp:WebPartZone>     <asp:WebPartZone                  Css         Runat="server" />     <asp:CatalogZone                  Css         Runat="server">         <ZoneTemplate>         <asp:DeclarativeCatalogPart                          Runat="server">             <WebPartsTemplate>         <user:AdministratorPart                          title="Administrator Part"             runat="server" />         <user:SerfPart                          title="Serf Part"             runat="server" />             </WebPartsTemplate>         </asp:DeclarativeCatalogPart>         <asp:PageCatalogPart                          Runat="server" />         </ZoneTemplate>     </asp:CatalogZone>     </form> </body> </html>

After you open the page in Listing 28.19, you won't see any Web Parts. If you log in with the username Tom and password secret, you'll see the SerfPart Web Part. If you log in with the user name Bill and password secret, you'll see both the SerfPart and AdministratorPart Web Part (Bill is a member of both the Administrator and Serf roles).

The AuthorizeWebPart event handler consists of the following single line of code:

e.IsAuthorized = User.IsInRole( GetFolder(e.Path) )


The GetFolder() method returns the root folder of the Web Part being authorized. In other words, it returns the name of the folder where the User Control that corresponds to the Web Part is located. If the name of the root folder matches one of the current user's roles, then the Web Part is authorized and it is displayed in the page.

Filtering by Custom Control Type

You can't filter a True Web Part by its path because a True Web Part doesn't have a path. However, you can do something similar. Rather than filter a True Web Part by its path, you can filter a True Web Part by its type.

In this section, two Web Part base classes are created, named AdministratorWebPartBase and SerfWebPartBase. Anyone who is a member of the Administrator role can see any Web Part that inherits directly from the AdministratorWebPartBase class, and anyone who is a member of the Serf role can see any Web Part that inherits directly from the SerfWebPartBase class.

The AdministratorWebPartBase and SerfWebPartBase classes are contained in Listing 28.20 and Listing 28.21.

Listing 28.20. App_Code\AdministratorWebPartBase.cs

Imports System Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' Base class for all Web Parts that     ''' an Administrator is authorized to see     ''' </summary>     Public MustInherit Class AdministratorWebPartBase         Inherits WebPart     End Class End Namespace

Listing 28.21. App_Code\SerfWebPartBase.cs

Imports System Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' Base class for all Web Parts that     ''' a member of the Serf role is authorized     ''' to see.     ''' </summary>     Public MustInherit Class SerfWebPartBase         Inherits WebPart     End Class End Namespace

Now that we have the base classes, we can inherit any number of Administrator and Serf Web Parts from the base classes. Listing 28.22 and Listing 28.23 contain an Administrator Web Part and a Serf Web Part.

Listing 28.22. App_Code\AdministratorPart.cs

Imports System Imports System.Web.UI Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' A Web Part that only an Administrator can see     ''' </summary>     Public Class AdministratorPart         Inherits AdministratorWebPartBase         Private _title As String = "Administrator Part"         Public Overrides Property Title() As String             Get                 Return _title             End Get             Set(ByVal Value As String)                 _title = value             End Set         End Property         Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)             writer.RenderBeginTag(HtmlTextWriterTag.H3)             writer.Write("Administrator Part")             writer.RenderEndTag()         End Sub     End Class End Namespace

Listing 28.23. App_Code\SerfPart.cs

Imports System Imports System.Web.UI Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' A Web Part that only a Serf can see     ''' </summary>     Public Class SerfPart         Inherits SerfWebPartBase         Private _title As String = "Serf Part"         Public Overrides Property Title() As String             Get                 Return _title             End Get             Set(ByVal Value As String)                 _title = value             End Set         End Property         Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)             writer.RenderBeginTag(HtmlTextWriterTag.H3)             writer.Write("Serf Part")             writer.RenderEndTag()         End Sub     End Class End Namespace

Notice that the AdministratorPart inherits from the AdministratorWebPartBase class, and the SerfPart inherits from the SerfWebPartBase class. The authorization filter in Listing 28.24 takes advantage of that fact.

Listing 28.24. ShowAuthorizationType.aspx

[View full width]

<%@ Page Language="VB" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server">     ''' <summary>     ''' Create the Administrator and Serf roles and     ''' the Bill and Tom user accounts.     ''' </summary>     Private  Sub Page_Load()         If Not Roles.RoleExists("Administrator") Then             Roles.CreateRole("Administrator")             Roles.CreateRole("Serf")             Membership.CreateUser("Bill", "secret")             Membership.CreateUser("Tom", "secret")             Roles.AddUserToRoles("Bill", New String(){"Administrator", "Serf"})             Roles.AddUserToRole("Tom", "Serf")         End If     End Sub     ''' <summary>     ''' Authorizes a user to see a Web Part when the base type of the Web Part     ''' matches one of the user's roles     ''' </summary>     Protected  Sub WebPartManager1_AuthorizeWebPart(ByVal sender As Object, ByVal e As  WebPartAuthorizationEventArgs)         e.IsAuthorized = User.IsInRole(GetRoleFromType(e.Type))     End Sub     ''' <summary>     ''' Returns the name of the base class from a type     ''' after stripping the text WebPartBase     ''' </summary>     Private Function GetRoleFromType(ByVal partType As Type) As String         Dim typeName As String = partType.BaseType.Name         Return typeName.Replace("WebPartBase", String.Empty)     End Function     Private  Sub Page_PreRender()         Menu1.Visible = Request.IsAuthenticated     End Sub     Protected  Sub Menu1_MenuItemClick(ByVal sender As Object, ByVal e As MenuEventArgs)         WebPartManager1.DisplayMode = WebPartManager1.DisplayModes(e.Item.Text)     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <style type="text/css">         .login         {             border:solid 1px black;             background-color:white;         }         .column         {             float:left;             width:30%;             height:200px;             margin-right:10px;             border:solid 1px black;             background-color: white;         }         .menu         {             margin:5px 0px;         }         html         {             background-color:#eeeeee;         }     </style>     <title>Show Authorization Type</title> </head> <body>     <form  runat="server">     <asp:WebPartManager                  OnAuthorizeWebPart="WebPartManager1_AuthorizeWebPart"         Runat="server" />     <asp:Login                  Css         TitleText=""         Orientation="horizontal"         DisplayRememberMe="false"         Runat="server" />     <asp:Menu                  OnMenuItemClick="Menu1_MenuItemClick"         Orientation="Horizontal"         Css         Runat="server">         <Items>         <asp:MenuItem Text="Browse" />         <asp:MenuItem Text="Design" />         <asp:MenuItem Text="Catalog" />         </Items>     </asp:Menu>     <asp:WebPartZone                  Css         Runat="server">         <ZoneTemplate>         <custom:AdministratorPart                          runat="Server" />         <custom:SerfPart                          runat="server" />         </ZoneTemplate>     </asp:WebPartZone>     <asp:WebPartZone                  Css         Runat="server" />     <asp:CatalogZone                  Css         Runat="server">         <ZoneTemplate>         <asp:DeclarativeCatalogPart                          Runat="server">             <WebPartsTemplate>             <custom:AdministratorPart                                  runat="Server" />             <custom:SerfPart                                  runat="server" />             </WebPartsTemplate>         </asp:DeclarativeCatalogPart>         </ZoneTemplate>     </asp:CatalogZone>     </form> </body> </html>

Once again, Tom only can see the SerfPart Web Part, and Bill can see both the SerfPart and AdministratorPart Web Parts. The AuthorizeWebPart event handler consists of the following single line of code:

e.IsAuthorized = User.IsInRole(GetRoleFromType(e.Type))


The GetroleFromType() method returns the name of the base type of the current Web Part (and strips the string "WebPartBase" from the name). If the current user is a member of the role represented by the base type, then the user can see the Web Part.




ASP. NET 2.0 Unleashed
ASP.NET 2.0 Unleashed
ISBN: 0672328232
EAN: 2147483647
Year: 2006
Pages: 276

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net