我們知道對於權限管理這塊,采取的思想就是RBAC
每個用戶對應一個角色,我們只需要對這個角色進行分配相應的權限即可,也就是給這個用戶分配了權限,這樣管理起來很方便,設計也很簡答,大概就是用戶表,角色表,模塊表,在加上一個角色與模塊對應的表就可以了,然后根據不同的用戶權限,顯示相應的模塊或者提示沒有權限訪問,這里要說的就是,對每個頁面的訪問權限,如果都寫的話,這么多的頁面是個很大的工作量,類似判斷用戶是否登錄一樣,在asp.net中我們完全可以使用Forms驗證來代替使用session每個頁面都要判斷的做法,同樣,在這里我們也可以通過HttpModule來直接過濾掉沒有訪問權限的頁面,方便多了,我們知道HttpModule可以再服務器端接收處理之前進行相關的過濾,這點給我們提供很大的方便,我們完全可以利用它的這一點,具體的來看看下:

{
private static string loginPage = " login.aspx ";
#region IHttpModule Members
public void Dispose()
{
// 此處放置清除代碼。
}
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(checkUserRight);
}
/// <summary>
/// 檢測用戶權限
/// </summary>
void checkUserRight( object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender; // 獲取應用程序
string url = HttpContext.Current.Request.Url.ToString(); // 獲取Url
int start=url.LastIndexOf( ' / ') + 1; // 查找URL中最后一個/的位置
int end=url.IndexOf( ' ? ',start); // 查找URL中?位置
string requestPage = null;
if (end < 0) end = url.Length - 1;
requestPage=url.Substring(start, end - start + 1); // 得到所請求的頁面
requestPage = requestPage.ToLower();
if (requestPage == loginPage) return;
if (!isProtectedResource(requestPage)) return;
User user=SJL.Web.HttpCode.WebUtility.currentUser; // 獲得當前用戶
if (user== null)
{
application.Response.Redirect( " ~/Login.aspx ");
return;
}
if (SJL.Bll.UserRight.UserBLL.isAdmin(user)) return;
// 檢測用戶權限
if (!SJL.Bll.UserRight.RoleRightBLL.canAccessPage(user.RoleID, requestPage))
application.Response.Redirect( " ~/AccessDeny.htm ");
}
/// <summary>
/// 判斷頁面是否為受權限管理保護的資源(如Aspx等)
/// </summary>
/// <param name="page"> 所請求的頁面 </param>
/// <returns> 是否受保護 </returns>
bool isProtectedResource( string page)
{
page = page.ToLower();
System.Collections.Generic.List<String> protectedFiles =
new System.Collections.Generic.List< string>(); // 受保護資源的擴展名
protectedFiles.AddRange( new string[] { " .aspx ", " .asmx ", " .ashx " });
string found=protectedFiles.Find(s => page.EndsWith(s));
if (found == null)
return false;
ApplicationModule module = SJL.Bll.UserRight.ApplicationModuleBLL.getByUrl(page);
if (module == null) return false;
return !module.IsPublic; // 如果頁面為公共模塊則不受保護
}
#endregion
public void OnLogRequest(Object source, EventArgs e)
{
// 可以在此放置自定義日志記錄邏輯
}
}
Web.coinfig中配置下
<httpModules>
<add name="CheckUserModule" type="SJL.Web.HttpCode.CheckUserModule"/>
</httpModules>
先判斷是否登錄,是否是受保護的資源,然后根據url來判斷是否有權限訪問!
我們可以根據自己需要控制的權限去設置,比如一個企業級的軟件,我們需要控制菜單的頁面,那么這個時候,我們只需要判斷
1、.aspx結尾的文件,httpModules過濾的時候也會過濾下比如css,js,ashx等頁面,在這里因為受權限保護的只有aspx結尾的,所有只需要對aspx結尾的進行過濾判斷即可
2、是否是受權限控制的頁面
3、如果沒有登錄,則跳到登錄頁面
4、如果是受權限控制的頁面,那么就看看此時登錄的用戶是否有訪問的這個頁面的url權限即可
注意點:
1、因為這種方式主要是對頁面進行權限判斷,所以為了權限設置到位,比較嚴,最好每一個需要權限保護的功能都單獨做一個頁面,不要和其他頁面套在一起,放置權限設置混亂
2、判斷權限頁面的時候,對訪問的頁面和數據庫保存的頁面都要去除參數和目錄,比如/user/user_edit.aspx?id=5,那么這個時候我們就要截取獲得user_edit.aspx用來判斷,否則,就會出現權限控制不嚴格的情況,比如列表 /user/user_list.aspx,如果你對訪問過來的url沒有截取判斷,那么訪問user_list.aspx?page=5則會通過,但是事實上我們已經控制這個頁面不讓訪問了,就是因為url不同導致權限控制有問題,所以這點一定要注意!
采用httpModule的好處就是一步操作就可以完成權限控制和未登錄驗證,效果很好,改變了傳統的每個頁面都需要判斷的寫法
Code:
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using shuang.Model;
/// <summary>
/// CheckUserModule 的摘要說明
/// </summary>
public class CheckRoleModule : IHttpModule
{
public static string loginPage = " login.aspx ";
public CheckRoleModule()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
#region IHttpModule 成員
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(checkUserMenu);
}
void checkUserMenu( object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender; // 獲取應用程序
string url = HttpContext.Current.Request.Url.ToString(); // 獲取Url
int start = url.LastIndexOf( ' / ') + 1; // 查找URL中最后一個/的位置
int end = url.IndexOf( ' ? ', start); // 查找URL中?位置
string requestPage = null;
if (end < 0) end = url.Length;
requestPage = url.Substring(start, end - start); // 得到所請求的頁面
// 截取后綴
if (requestPage == loginPage) return;
string requestPageSuffix = requestPage.Substring(requestPage.LastIndexOf( " . ") + 1);
if (requestPageSuffix != " aspx ")
{
return;
}
string user = OperateCommon.currentUser;//對每一個頁面都要判斷是否登錄
if (user == null)
{
application.Response.Write( " <script language='javascript'>parent.location.href=' " + Common.ApplicationRootPath + " /login.aspx';</script> ");
return;
}
else
{
// 查看是否是菜單權限控制頁面
// requestPage = url.Substring(start);
if (!isProtectedResource(requestPage)) return;
// 檢測用戶權限
if (!OperateCommon.isPross(user,requestPage)) {
Common.showMsg( " 0 ", " 你沒有訪問該頁面的權限,請聯系管理員 ");
}
}
}
/// <summary>
/// 判斷頁面是否為受權限管理保護的資源
/// </summary>
/// <param name="page"> 所請求的頁面 </param>
/// <returns> 是否受保護 </returns>
bool isProtectedResource( string page)
{
// page = page.ToLower();
List<String> protectedFiles =OperateCommon.GetMenu(); // 受保護的頁面
// 讀取所有菜單欄目的url
bool fig = false;
foreach ( string item in protectedFiles)
{
if(item==page)
{
fig = true;
break;
}
}
return fig;
}
public void Dispose()
{
// throw new NotImplementedException();
}
#endregion
}
OPerateCommon

using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using shuang.BLL;
using shuang.Model;
using System.Collections.Generic;
/// <summary>
/// OperateCommon 的摘要說明
/// </summary>
public class OperateCommon
{
public OperateCommon()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
private const string SessionUser = " LoginName "; // 登錄用戶
private static string loginName = "";
public static string currentUser
{
get
{
if (HttpContext.Current == null)
{
return null;
}
else
{
if (HttpContext.Current.Session[SessionUser] != null)
{
return HttpContext.Current.Session[SessionUser].ToString();
}
}
return null;
}
set
{
HttpContext.Current.Session[SessionUser] = value;
}
}
public static void getLoginName()
{
if (currentUser!= null)
{
loginName = HttpContext.Current.Session[SessionUser].ToString();
}
else
{
HttpContext.Current.Response.Redirect( " ~/logout.aspx ");
}
}
/// <summary>
/// 檢測用戶的訪問權限
/// </summary>
/// <returns></returns>
public static bool isPross( string loginName, string requestPage)
{
UserBLL bll = new UserBLL();
RoleBLL rolebll = new RoleBLL();
menuBLL menubll = new menuBLL();
bool fig = false;
DataSet ds = bll.GetList( " userName=' "+loginName+ " ' ");
if (ds != null)
{
string roleId = ds.Tables[ 0].Rows[ 0][ " userRole "].ToString();
Role role = rolebll.GetModel(Convert.ToInt32(roleId));
string menuId = role.roleMenulimit;
DataSet dsMenu = menubll.GetList( " menuId in( "+menuId+ " ) ");
foreach (DataRow row in dsMenu.Tables[ 0].Rows)
{
string url = row[ " url "].ToString();
int start = url.LastIndexOf( ' / ') + 1; // 查找URL中最后一個/的位置
int end = url.IndexOf( ' ? ', start);
string url1 = null;
if (end < 0) end = url.Length;
url1 = url.Substring(start, end - start);
if (url1 == requestPage)
{
fig= true;
break;
}
}
}
return fig;
}
/// <summary>
/// 獲取受保護的菜單頁面
/// </summary>
/// <returns></returns>
public static List< string> GetMenu()
{
menuBLL menubll = new menuBLL();
DataSet ds = menubll.GetList( " parent!=0 ");
List< string> menuList = new List< string>();
foreach (DataRow row in ds.Tables[ 0].Rows)
{
string url = row[ " url "].ToString();
int start = url.LastIndexOf( ' / ') + 1; // 查找URL中最后一個/的位置
// url = url.Substring(start);
int end = url.IndexOf( ' ? ', start);
string requestPage = null;
if (end < 0) end = url.Length;
requestPage = url.Substring(start, end - start);
menuList.Add(requestPage);
}
return menuList;
}
}
web.config
<add name="CheckUserModule" type="CheckRoleModule"/>
這樣就完成了權限限制,文件過濾等問題...