global.asax中代码,定义两个事件application_BeginRequest 与Application_AuthenticateRequest事件
application_BeginRequest 事件把站点配置缓存到Cache中
using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Security;
using System.Security.Principal;
using System.Web.Security;
using System.Web.SessionState;
using System.Threading;
using System.Globalization;
namespace MyStarterKit.Portal.Web
{
/// <summary>
/// Global 的摘要说明。
/// </summary>
public class Global : System.Web.HttpApplication
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
public Global()
{
InitializeComponent();
}
/// <summary>
/// 在 ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Application_BeginRequest(Object sender, EventArgs e)
{
int tabIndex = 0;
int tabId = 1;
// Get TabIndex from querystring
// 在当前请求字符中获取tabIndex的值
if (Request.Params["tabindex"] != null)
{
tabIndex = Int32.Parse(Request.Params["tabindex"]);
}
// Get TabID from querystring
// 在当前请求字符中获取tabId的值
if (Request.Params["tabid"] != null)
{
tabId = Int32.Parse(Request.Params["tabid"]);
}
// Build and add the PortalSettings object to the current Context
// 建立并添加PortalSettings(门户站点设置对象)到HttpContext对象中
Context.Items.Add("PortalSettings", new PortalSettings(tabIndex, tabId));
// Retrieve and add the SiteConfiguration DataSet to the current Context
// 将站点设置信息(数据集形式)添加到HttpContext中
HttpContext.Current.Items.Add("SiteSettings", Configuration.GetSiteSettings());
// 全球化 Web 窗体页
try
{
if (Request.UserLanguages != null)
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
else
// Default to English if there are no user languages
// 已英语为默认设置
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
}
catch
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");
}
}
/// <summary>
/// 当安全模块已建立用户标识时发生。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Request.IsAuthenticated == true)
{
String[] roles;
#region 原来错误的代码
/*
这段代码有个很严重的Bug,我们先用这个帐户登陆,去创建一个Consultant角色的帐户:[email protected] 然后马上关闭浏览器
(注意我这里说的关闭是用MOUSE点击浏览器关闭按钮而不是用程序提供的注销按钮) 再打开浏览器进入登陆页,用帐户:[email protected]登陆系统.
这时我们就可以利用顾问角色的帐户访问管理信息页面
原因:因为当Cookie(重名都是portalroles)还存在时就不会重新读取数据,而是读原来的
这个网址http://www.cnblogs.com/aierong/archive/2005/01/17/93113.html 中有关于使Cookie唯一化来解决的办法
*/
/*
// Create the roles cookie if it doesn't exist yet for this session.
// 将用户角色信息存入到cookie
if ((Request.Cookies["portalroles"] == null) || (Request.Cookies["portalroles"].Value == ""))
{
//当Cookies中没有时,从数据库中读取
// Get roles from UserRoles table, and add to cookie
UsersDB user = new UsersDB();
roles = user.GetRoles(User.Identity.Name);
// Create a string to persist the roles
// 以字符串的形式存储用户角色信息用";"分隔,一个用户的多个角色
String roleStr = "";
foreach (String role in roles)
{
roleStr += role;
roleStr += ";";
}
// Create a cookie authentication ticket.
// 创建身份角色验证的凭据
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // version 版本
Context.User.Identity.Name, // user name cookie 名
DateTime.Now, // issue time 发布日期
DateTime.Now.AddHours(1), // expires every hour 过期日期
false, // don't persist cookie 持久性(false)
roleStr // roles 用户定义的数据初始化(";"分隔的角色字符串)
);
// Encrypt the ticket
// 加密凭证
String cookieStr = FormsAuthentication.Encrypt(ticket);
// Send the cookie to the client
// 将存有用户角色信息的字符串存入cookie
Response.Cookies["portalroles"].Value = cookieStr;
Response.Cookies["portalroles"].Path = "/";
Response.Cookies["portalroles"].Expires = DateTime.Now.AddMinutes(1);
}
else
{
//当Cookies中有时,从Cookies中读取
// Get roles from roles cookie
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies["portalroles"].Value);
//convert the string representation of the role data into a string array
ArrayList userRoles = new ArrayList();
foreach (String role in ticket.UserData.Split( new char[] {';'} ))
{
userRoles.Add(role);
}
roles = (String[]) userRoles.ToArray(typeof(String));
}
*/
#endregion
//不存入Cookie每次都从数据库中读取
UsersDB user = new UsersDB();
roles = user.GetRoles(User.Identity.Name);
// Create a string to persist the roles
// 以字符串的形式存储用户角色信息用";"分隔,一个用户的多个角色
String roleStr = "";
foreach (String role in roles)
{
roleStr += role;
roleStr += ";";
}
// Create a cookie authentication ticket.
// 创建身份角色验证的凭据
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // version 版本
Context.User.Identity.Name, // user name cookie 名
DateTime.Now, // issue time 发布日期
DateTime.Now.AddHours(1), // expires every hour 过期日期
false, // don't persist cookie 持久性(false)
roleStr // roles 用户定义的数据初始化(";"分隔的角色字符串)
);
// Add our own custom principal to the request containing the roles in the auth ticket
// 从 GenericIdentity 和角色名称数组(GenericIdentity 表示的用户属于该数组)初始化 GenericPrincipal 类的新实例。
Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
}
/// <summary>
/// 返回站点路径根路径
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static string GetApplicationPath(HttpRequest request)
{
string path = string.Empty;
try
{
if(request.ApplicationPath != "/")
path = request.ApplicationPath;
}
catch (Exception e)
{
throw e;
}
return path;
}
#region Web 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
}
#endregion
}
}
/// <summary>
/// 门户站点设置的信息
/// </summary>
public class PortalSettings
{
public int PortalId; //门户站点Id
public String PortalName; //门户站点名称
public bool AlwaysShowEditButton; //是否显示编辑按钮
public ArrayList DesktopTabs = new ArrayList(); //门户站点“桌面浏览器”显示部分的导航栏标签的ArrayList
public ArrayList MobileTabs = new ArrayList();
public TabSettings ActiveTab = new TabSettings(); //当前标签
//*********************************************************************
//
// PortalSettings Constructor
//
// The PortalSettings Constructor encapsulates all of the logic
// necessary to obtain configuration settings necessary to render
// a Portal Tab view for a given request.
//
// These Portal Settings are stored within PortalCFG.xml, and are
// fetched below by calling config.GetSiteSettings().
// The method config.GetSiteSettings() fills the SiteConfiguration
// class, derived from a DataSet, which PortalSettings accesses.
//
//*********************************************************************
/// <summary>
/// 构造门户站点设置信息对象
/// </summary>
/// <param name="tabIndex"></param>
/// <param name="tabId"></param>
public PortalSettings(int tabIndex, int tabId)
{
// Get the configuration data
// 获取配置文件数据
SiteConfiguration siteSettings = Configuration.GetSiteSettings();
// Read the Desktop Tab Information, and sort by Tab Order
// 根据标签排序号按顺序读取“桌面浏览器”上显示的导航栏标签信息
foreach(SiteConfiguration.TabRow tRow in siteSettings.Tab.Select("", "TabOrder"))
{
//构造标签详细信息对象实例
TabStripDetails tabDetails = new TabStripDetails();
//赋值
tabDetails.TabId = tRow.TabId;
tabDetails.TabName = tRow.TabName;
tabDetails.TabOrder = tRow.TabOrder;
tabDetails.AuthorizedRoles = tRow.AccessRoles;
//将对象添加到DesktopTabs中
this.DesktopTabs.Add(tabDetails);
}
// If the PortalSettings.ActiveTab property is set to 0, change it to the TabID of the first tab in the DesktopTabs collection
// 设置当前活动标签,当前标签的TabId为0时,取“桌面浏览器”的标签列表的第一项为当前项
if(this.ActiveTab.TabId == 0)
{
this.ActiveTab.TabId = ((TabStripDetails)this.DesktopTabs[0]).TabId;
}
// Read the Mobile Tab Information, and sort by Tab Order
foreach(SiteConfiguration.TabRow mRow in siteSettings.Tab.Select("ShowMobile='true'", "TabOrder"))
{
TabStripDetails tabDetails = new TabStripDetails();
tabDetails.TabId = mRow.TabId;
tabDetails.TabName = mRow.MobileTabName;
tabDetails.AuthorizedRoles = mRow.AccessRoles;
this.MobileTabs.Add(tabDetails);
}
// Read the Module Information for the current (Active) tab
// 获取当前活动标签所在行信息
SiteConfiguration.TabRow activeTab = siteSettings.Tab.FindByTabId(tabId);
// Get Modules for this Tab based on the Data Relation
// 找到当前标签的关联的模块信息
foreach(SiteConfiguration.ModuleRow moduleRow in activeTab.GetModuleRows())
{
ModuleSettings moduleSettings = new ModuleSettings();
moduleSettings.ModuleTitle = moduleRow.ModuleTitle;
moduleSettings.ModuleId = moduleRow.ModuleId;
moduleSettings.ModuleDefId = moduleRow.ModuleDefId;
moduleSettings.ModuleOrder = moduleRow.ModuleOrder;
moduleSettings.TabId = tabId;
moduleSettings.PaneName = moduleRow.PaneName;
moduleSettings.AuthorizedEditRoles = moduleRow.EditRoles;
moduleSettings.CacheTime = moduleRow.CacheTimeout;
moduleSettings.ShowMobile = moduleRow.ShowMobile;
// ModuleDefinition data
SiteConfiguration.ModuleDefinitionRow modDefRow = siteSettings.ModuleDefinition.FindByModuleDefId(moduleSettings.ModuleDefId);
moduleSettings.DesktopSrc = modDefRow.DesktopSourceFile;
moduleSettings.MobileSrc = modDefRow.MobileSourceFile;
this.ActiveTab.Modules.Add(moduleSettings);
}
// Sort the modules in order of ModuleOrder
this.ActiveTab.Modules.Sort();
// Get the first row in the Global table
// 获取全局设置
SiteConfiguration.GlobalRow globalSettings = (SiteConfiguration.GlobalRow) siteSettings.Global.Rows[0];
// Read Portal global settings
// 读取门户站点的全局设置
this.PortalId = globalSettings.PortalId;
this.PortalName = globalSettings.PortalName;
this.AlwaysShowEditButton = globalSettings.AlwaysShowEditButton;
this.ActiveTab.TabIndex = tabIndex;
this.ActiveTab.TabId = tabId;
this.ActiveTab.TabOrder = activeTab.TabOrder;
this.ActiveTab.MobileTabName = activeTab.MobileTabName;
this.ActiveTab.AuthorizedRoles = activeTab.AccessRoles;
this.ActiveTab.TabName = activeTab.TabName;
this.ActiveTab.ShowMobile = activeTab.ShowMobile;
}
}
#endregion
desktop.aspx文件
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace MyStarterKit.Portal.Web
{
/// <summary>
/// DesktopDefault 的摘要说明。
/// “桌面浏览器”程序的首页
/// </summary>
public class DesktopDefault : System.Web.UI.Page
{
protected System.Web.UI.HtmlControls.HtmlTableCell LeftPane;
protected System.Web.UI.HtmlControls.HtmlTableCell ContentPane;
protected System.Web.UI.HtmlControls.HtmlTableCell RightPane;
protected Literal pageTitle;
/// <summary>
/// 初始化页面显示
/// </summary>
private void InitClass()
{
//从HttpContext中获取全局设置对象
PortalSettings portalSettings = (PortalSettings) HttpContext.Current.Items["PortalSettings"];
//设置标题栏
pageTitle.Text = portalSettings.PortalName;
// Ensure that the visiting user has access to the current page
// 单当前用户的角色不在当前活动标签的可访问角色中时,重定向到访问错误页
if (PortalSecurity.IsInRoles(portalSettings.ActiveTab.AuthorizedRoles) == false)
{
Response.Redirect("~/Admin/AccessDenied.aspx");
}
// Dynamically inject a signin login module into the top left-hand corner
// of the home page if the client is not yet authenticated
//判断是否显示登陆信息(当用户未验证且显示页面为第一页时)
if ((Request.IsAuthenticated == false) && (portalSettings.ActiveTab.TabIndex == 0))
{
LeftPane.Controls.Add(Page.LoadControl("~/DesktopModules/SignIn.ascx"));
LeftPane.Visible = true;
}
// Dynamically Populate the Left, Center and Right pane sections of the portal page
// 当前标签下的模块数大于0时,分别在左中右三个方块中显示当前标签下的模块
if (portalSettings.ActiveTab.Modules.Count > 0)
{
// Loop through each entry in the configuration system for this tab
// 在当前标签的模块列表中依次读取模块
foreach (ModuleSettings _moduleSettings in portalSettings.ActiveTab.Modules)
{
//在页面中找到存放指定控件的板块(左中右)
Control parent = Page.FindControl(_moduleSettings.PaneName);
// If no caching is specified, create the user control instance and dynamically
// inject it into the page. Otherwise, create a cached module instance that
// may or may not optionally inject the module into the tree
//如果控件的缓存时间为0
if ((_moduleSettings.CacheTime) == 0)
{
//构造用户控件
PortalModuleControl portalModule = (PortalModuleControl) Page.LoadControl(_moduleSettings.DesktopSrc);
portalModule.PortalId = portalSettings.PortalId;
portalModule.ModuleConfiguration = _moduleSettings;
//在指定板块中加载控件
parent.Controls.Add(portalModule);
}
else
{
CachedPortalModuleControl portalModule = new CachedPortalModuleControl();
portalModule.PortalId = portalSettings.PortalId;
portalModule.ModuleConfiguration = _moduleSettings;
parent.Controls.Add(portalModule);
}
// Dynamically inject separator break between portal modules
// 加入控件之间的分隔符
parent.Controls.Add(new LiteralControl("<" + "br" + ">"));
//将存放控件的板块置位可见
parent.Visible = true;
}
}
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
this.InitClass();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
}
#endregion
}
}