Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Real - World ASP .NET—Building a Content Management System - StephenR. G. Fraser

.pdf
Скачиваний:
68
Добавлен:
24.05.2014
Размер:
4.59 Mб
Скачать

Listing 15-8: The DeployDeploy Codebehind, Protecting Content by the Zone's Protection Value

private void bnDeploy_Click(object sender, System.EventArgs e)

{

bool protectedZone = false;

int zoneVal;

Distribution dist = new Distribution(appEnv.GetConnection());

content.SetStatus(cid, ver, StatusCodes.Deployed);

int avgRank = new ContentRank(appEnv.GetConnection()).GetRankID("Average");

for (int i = 0; i < lbZones.Items.Count; i++)

{

if (lbZones.Items[i].Selected)

{

zoneVal = Convert.ToInt32(lbZones.Items[i].Value); dist.Insert(cid, ver, zoneVal, avgRank);

if (!protectedZone)

protectedZone = zone.IsProtected(zoneVal);

}

}

if (protectedZone)

content.SetProtected(cid, ver, (protectedZone ? 1 : 0));

Response.Redirect("DeployList.aspx");

}

The code for checking to see whether a zone is protected is found in the Zone database helper IsProtected() method (see Listing 15-4). As you can see, it simply checks to see whether the selected row has a Protected value greater than zero. CMS.NET could have written its own stored procedure to handle this method, but because it is so similar to the GetZone() method, it was far easier just to call that instead.

Listing 15-9: The Zone Database Helper Methods Checking for a Protected Row

public bool IsProtected(int ZoneID)

{

DataRow dr = GetZone(ZoneID);

return (Convert.ToInt32(dr["Protected"]) > 0);

}

public DataRow GetZone(int ZoneID)

{

//SELECT *

//FROM Zone

//WHERE ZoneID=@ZoneID

SqlCommand Command = new SqlCommand("Zone_GetZone", m_Connection); Command.CommandType = CommandType.StoredProcedure; Command.Parameters.Add(new SqlParameter("@ZoneID", SqlDbType.Int)); Command.Parameters["@ZoneID"].Value = ZoneID;

SqlDataAdapter DAdpt = new SqlDataAdapter(Command);

DataSet ds = new DataSet();

DAdpt.Fill(ds, "Zone");

if (ds.Tables["Zone"].Rows.Count > 0) return ds.Tables["Zone"].Rows[0];

else

return null;

}

Protected CDA Directory

As previously pointed out, protected content is accessed through its own set of Web forms. These forms are in their own directory and use ASP.NET authentication. If you recall from Chapter 12, to implement ASP.NET authentication, you simply have to add a web.config file to that directory.

This web.config file is virtually the same as any other you have already implemented from this book, as you can see in Figure 15-5. It basically denies all unauthenticated users. The only difference between this version and the previous ones you have seen is

that it doesn't use the <allow roles> element. CMS.NET's CDA doesn't restrict Web site users by roles. It simply cares that the user is authenticated. This doesn't mean, though, that you can't add roles to this file in the future, restricting content to specific roles or, more accurately in this case, groups of users.

Listing 15-10: The CDA/Protected web.config File

<?xml version="1.0" encoding=" utf-8" ?>

<configuration>

<system.web>

<authorization>

<deny users="?" />

</authorization>

</system.web>

</configuration>

Protected Default Web Forms

CMS.NET does not display protected content any differently than unprotected content. This is not to say that your CMS can't have additional things displayed with protected content or maybe even a completely different look and feel.

Because what is displayed is identical, all CMS.NE T did to create protected Web forms was copy the default ContentPg, ZonePg, and StoryPg Web pages to the Protected directory.

Obviously, in the Web design code of each Web page, the <#@ Page Inherits=""> attribute had to be changed to reflect the new namespace of the Codebehind that is now in the Protected directory.

A little less obvious, though, is the need to change every occurrence of a User Control to a reference to its location in the parent directory because the User Controls were not copied to the Protected directory. For example, here is how it needs to be done in a Web design and a Codebehind:

<%@ Register TagPrefix=" cmsnet" TagName=" Header" Src="../Header.ascx" %>

HeadlineTeaser hlt = (HeadlineTeaser) LoadControl("../HeadlineTeaser.ascx");

There was no need to copy the User Controls to the Protected directory because a user can't access them directly anyway. They can only be called from within a Web page. Thus, they are protected indirectly because they are called by a protected Web page.

Copying the User Controls to the Protected directory would only mean more redundant code. As it is, CMS.NET has very similar Web page code in two places. But, as you will see, the code is not identical. Plus, in the future, it is very possible that protected content will display more information than unprotected content and thus will be even more different than their unprotected equivalents.

Updates to Default Web Forms

Each of the original default content display Web forms needs minor changes to support protected content. Most of the changes revolve around populating navigation URLs to reflect the new, protected content and to stop a sneaky user from trying to view protected content using the unprotected content display Web forms.

HomePg Web Page

No coding changes are needed on the HomePg Web page to protect content. The home page should be visible to all, at the very least to say that you need permission to access the rest of the site.

The following changes are, in fact, to add the Login and Logout User Controls to the NavBar (see Figure 15-7 and Figure 15-8). This book will only show this change once here in the HomePg, even though the change needs to be done in all Web forms— protected and unprotected.

Figure 15-7: The HomePg Web page with Login User Control

Figure 15-8: The HomePg Web page with Logout User Cont rol

The HomePg Web design (see Listing 15-11) shows the simple addition of the Register directive for Login and Logout and their tags being added to the NavBar cell of the HomePg layout table.

Listing 15-11: The HomePg Web Page Design

<%@ Page language=" c#" Codebehind=" HomePg.aspx.cs" AutoEventWireup=" false"

Inherits=" CMSNET.CDA.HomePg" %>

<%@ Register TagPrefix=" cmsnet" TagName=" Header" Src=" Header.ascx" %>

<%@ Register TagPrefix=" cmsnet" TagName=" NavBar" Src=" NavBar.ascx" %>

<%@ Register TagPrefix=" cmsnet" TagName=" Login" Src=" Login.ascx" %>

<%@ Register TagPrefix=" cmsnet" TagName=" Logout" Src=" Logout.ascx" %>

<%@ Register TagPrefix=" cmsnet" TagName=" Footer" Src=" Footer.ascx" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML> <HEAD>

<title>CMS.NET Home</title> </HEAD>

<body MS_POSITIONING=" FlowLayout">

<form id=" HomePg" method=" post" runat=" server">

<TABLE cellSpacing="8" cellPadding="1" width="100%" border="0"> <TR>

<TD colSpan="2" >

<cmsnet:Header id=" Header" Level=" home" runat=" server"> </cmsnet:Header>

</TD > </TR> <TR>

<TD vAlign=" top" width="20%" bgColor="#8cd3ef"> <br>

<P>

<cmsnet:NavBar id=" MainNavBar" runat=" server"> </cmsnet:NavBar>

</P> <P>

<cmsnet:Login id=" ucLogin" runat=" server" Visible=" False"> </cmsnet:Login>

<cmsnet:Logout id=" ucLogout" runat=" server" Visible=" False"> </cmsnet:Logout >

</P> </TD >

<TD width="80%" vAlign=" top"> <H1>

<FONT color=" darkslategray">Welcome to CMS.NET!</FONT>

</H1>

<P>

(Add home page stuff here)

</P> </TD >

</TR > <TR>

<TD colSpan="2">

<cmsnet:Footer id=" Footer" runat=" server"> </cmsnet:Footer>

</TD >

</TR >

</TABLE>

</form>

</body>

</HTML>

You might also note that the User Controls both have their Visible attributes set to false, which means that the Codebehind needs to change one of them to true to be visible to the Web user.

The HomePg Codebehind (see Listing 15-12) is pretty self-explanatory. First, you have to manually add the User Controls to the Codebehind because the Visual Studio .NET code generator doesn't do it for you. Then, within the Page_Load() method, examine the Request.IsAuthenticated property to see if the user has been authenticated. If the user is not authenticated, display the Login User Control. Otherwise, display the Logout User Control.

Listing 15-12: The HomePg Codebehind for Viewing Login and Logout User Controls

public class HomePg : CMSNET.Common.PageEx

{

protected CMSNET.CDA.NavBar MainNavBar; protected CMSNET.CDA.Login ucLogin; protected CMSNET.CDA.Logout ucLogout;

private void Page_Load(object sender, System.EventArgs e)

{

int Domain = Convert.ToInt32(Request.QueryString["Domain"]);

// First Time in no Domain specified if (Domain == 0)

Domain++;

MainNavBar.Domain = Domain;

if (!Request.IsAuthenticated) ucLogin.Visible = true;

else

ucLogout.Visible = true;

}

}

NavBar User Control

The NavBar Codebehind coding change to handle the redirect of protected content is really very simple (see Listing 15-13). All you need to do is place the string "Protected/" in front of every navigation URL that has a destination of a protected domain.

Listing 15-13: The NavBar Codebehind for Referencing Protected domains

private void Page_Load(object sender, System.EventArgs e)

{

...

foreach (DataRow dr in dt.Rows)

{

...

if (m_domain != Convert.ToInt32(dr["DomainID"]))

{

link = new HyperLink(); link.Text = dr["Title"].ToString();

link.NavigateUrl = buildDirectory(dr) + dr["DomainType"].ToString().Trim() + ".aspx?Domain=" + dr["DomainID"];

cell.Controls.Add(link);

}

...

}

}

private string buildDirectory (DataRow dr)

{

if (Convert.ToInt32(dr["Protected"]) == 0)

return "";

return "Protected/";

}

In other words, the Page_Load() method checks to see whether the Protected column in the Domain database is greater than zero. If it is, place "Protected/" in front of the NavigateUrl property.

This same code change needs to be done to the HeadlineTeaser User Control and the unprotected versions of the ContentPg and ZonePg Web pages. The only difference in each of these is that they are checking different databases for their protected NavigationUrls. The code is so similar that there is no need to include it here, but if you need it, you can find it on the Apress Web site (www.apress.com) in the Downloads section with all the other code in this book.

StoryPg Web Page

The final change is that you need to stop sneaky users from using the unprotected versions of the content viewers to view protected content. Until now, CMS.NET has been relying on the idea that the user will run the correct version of the viewer to view the content. This will enable ASP.NET to trap unauthenticated users.

Unfortunately, there is nothing stopping the user from manually accessing the same piece of content using the unprotected version of the Web form and thus bypassing the ASP.NET-imposed authentication security.

To combat this, one further check must be made within the unprotected version of the ContentPg, ZonePg, and StoryPg Web forms to verify that the content is not protected. This check is not needed in the protected versions because ASP.NET will not allow the Web page to run until the user has been authenticated.

The StoryPg Codebehind (see Listing 15-14) shows this final check. If the content is protected, check to see whether the user has been authenticated. If the user has not been authenticated, redirect to the Login Web page. Note the following code:

Listing 15-14: The StoryPg Codebehind for Verifying Content Protection

private void Page_Load(object sender, System.EventArgs e)

{

...

DataRow dr = content.GetContentForIDVer(curId, curVer);

if (Convert.ToInt32(dr["Protected"]) > 0)

{

if (!Request.IsAuthenticated)

{

Response.Redirect("../Login.aspx" +

"?URL=" + HttpUtility.UrlEncode(Request.RawUrl));

}

}

...

}

"?URL=" + HttpUtility.UrlEncode(Request.RawUrl));

This code places the current URL onto the Response. You need to use the UrlEncode() method because the current URL contains reserved characters that, later

on down the line, wreak havoc. In particular, the ampersand (&) in "&ver=" is interpreted as a separate parameter when the Login Web page tries to grab the URL out of the Request using Request.QueryString["URL"].

Summary

This chapter covered registering users and restricting content.

It started by describing some reasons why a Web site might protect its content. Then it covered what a Web page privacy policy is, discussed why you need one, and then showed the CMS.NET policy. Next, it covered user profiles and the two most common methods of populating them: the quick blitz and the slow retrieval. It then showed the registration portion of CMS.NET's implementation of the slow retrieval method. It followed this up by showing logging in and out of CMS. Finally, it covered the changes that need to be implemented to add protected content to CMS.NET.

List of Figures

Chapter 1: So, What is a Content Management System Anyway?

Figure 1-1: Content components

Figure 1-2: The content management application Figure 1-3: The metacontent management application Figure 1-4: A simple CMS flowchart

Chapter 2: Version Control

Figure 2-1: Easy version control

Figure 2-2: Complex version control

Chapter 3: Workflow

Figure 3-1: A simple order-fulfillment workflow

Figure 3-2: A simple, standard workflow

Figure 3-3: An enhanced standard workflow

Chapter 4: Personalization

Figure 4-1: The personalization process

Figure 4-2: Perceived value to a programmer

Figure 4-3: My Yahoo Screen shot reproduced with permission of Yahoo! Inc. © 2000 by Yahoo! Inc. YAHOO! and the YAHOO! logo are trademarks of Yahoo! Inc.

Figure 4-4: The law of diminishing returns

Chapter 5: Basics of Web Architecture

Figure 5-1: The 3-tier Web architecture

Figure 5-2: The n-tier Web architecture

Figure 5-3: The client side

Figure 5-4: The server side

Figure 5-5: The .NET Framework for Web development

Chapter 6: ASP.NET, C#, and Visual Studio .NET

Figure 6-1: The simple Dynamic Content Viewer Figure 6-2: The New Project dialog box

Figure 6-3: An empty project

Figure 6-4: The Dynamic Content Viewer design window Figure 6-5: The Insert Table dialog box

Figure 6-6: The Visual Studio .NET Toolbox Figure 6-7: The Add New Item dialog box Figure 6-8: The C# Property Wizard

Chapter 7: Database Development and ADO.NET

Figure 7-1: The Server Explorer

Figure 7-2: The Create Database dialog box Figure 7-3: The DCV_DB data diagram Figure 7-4: The Relationships property page Figure 7-5: The Add Table dialog box Figure 7-6: The View Design window

Figure 7-7: The ADO.NET class interaction Figure 7-8: The ADOToList list

Figure 7-9: The ADOToGrid DataGrid Figure 7-10: The Add New Item dialog box

Figure 7-11: The ADOToGrid DataGrid before facelift Figure 7-12: The DataGrid dialog box

Figure 7-13: A Dynamic Content CMA Figure 7-14: A Dynamic Content CMA design

Figure 7-15: The updated Dynamic Content Viewer

Chapter 8: XML

Figure 8-1: The Add Reference dialog box

Figure 8-2: The Add New Item dialog box

Figure 8-3: The ReadXML Web page

Figure 8-4: The Select User or Groups dialog box

Figure 8-5: The WriteXML Web page

Figure 8-6: The UpdateXML Web page

Figure 8-7: The Menu Web page

Chapter 9: A Quick Overview of CMS.NET

Figure 9-1: The Internet Information Services program Figure 9-2: The Virtual Directory Creation Wizard Figure 9-3: Setting the virtual directory alias

Figure 9-4: Setting the virtual directory

Figure 9-5: Setting the virtual directory access permissions Figure 9-6: The "I'm changing" Web page

Figure 9-7: Using the Server Explorer to add a database connection Figure 9-8: The Data Link Properties dialog box

Figure 9-9: Duplicate connections

Figure 9-10: Using Enterprise Manager to attach a database Figure 9-11: The Attach Database dialog box

Figure 9-12: Running CMSNET.sql in the Query Analyzer Figure 9-13: The "Welcome to the CMS.NET Setup" Web page Figure 9-14: The configure database Web page

Figure 9-15: The CMSNET Properties dialog box Figure 9-16: Setting up the administrator account

Figure 9-17: Successful completion of the setup procedure Figure 9-18: The CMS.NET administration login Web page Figure 9-19: Creating a power user

Figure 9-20: Creating content

Figure 9-21: Listing the author's content Figure 9-22: Viewing a content mistake Figure 9-23: CMS.NET's version control Figure 9-24: Viewing the corrected content

Соседние файлы в предмете Программирование