轉貼---》代碼閱讀總結之ASP.NET StartKit TimeTracker(角色權限)

最近開始看ASP.NET StartKit TimeTracker中代碼,它是一個典型的項目追蹤系統。
它比我前幾天看的ASP.NET StartKit Commerce複雜了許多。
例如:在ASP.NET StartKit TimeTracker開始有明顯的三層結構的設計。PL層,BLL層和DAL層。
同時開始在項目中引進了角色權限管理功能等等。

今天我們先討論角色權限的實現問題。

讓我們先看一角色權限設置的參考資料:
http://www.cnblogs.com/kwklover/archive/2004/06/29/19455.aspx

現在假如我們系統中有3 種角色:Service,Work,Manage

要是我們想在WebForm1.aspx禁止Service,Manage這2類角色的登陸用戶訪問,我們可以在Web.config文件中做下面設置:

<location path="WebForm1.aspx">
        <system.web>
            <authorization>
             <deny roles="Service,Manage" />
  <deny users="?" />
            </authorization>
        </system.web>
</location>

還有一種方式就是:建立三個文件夾,某一角色的人只能訪問某一文件夾裏的ASPX.NET文件


假如我有用戶a,他有Service,Work這2種角色,假如有頁面abc.aspx,它允許Work,Manage這2種角色的用戶訪問。
個人感覺這樣設置的靈活性不好,有沒有通過代碼控制的方法呢?
我編寫了如下代碼:實現單用戶可以多角色,單頁面多角色訪問。

讓我們先看Global.asax.cs中代碼,請注意看事件Application_AuthenticateRequest中的代碼實現。

using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Threading;
using System.Globalization;
using System.Configuration;

namespace BluepieCustomerService 
{
    
/// <summary>
    
/// Global 的摘要說明。
    
/// </summary>

    public class Global : System.Web.HttpApplication
    
{
        
/// <summary>
        
/// 必需的設計器變量。
        
/// </summary>

        private System.ComponentModel.IContainer components = null;
        
        
/// <summary>
        
/// 本系統自定義的角色之一“服務人員”
        
/// </summary>

        public const string ConstUserRoleNameService="Service";

        
/// <summary>
        
/// 本系統自定義的角色之一“普通工作人員”
        
/// </summary>

        public const string ConstUserRoleNameWork="Work";

        
/// <summary>
        
/// 本系統自定義的角色之一“管理人員”
        
/// </summary>

        public const string ConstUserRoleNameManage="Manage";
        
        
/// <summary>
        
/// 逗號字符串
        
/// </summary>

        public const string ConstStringComma=",";

        
/// <summary>
        
/// 百分號字符串
        
/// </summary>

        public const string ConstStringPercent="%";

        
/// <summary>
        
/// char 類型逗號
        
/// </summary>

        public const char ConstCharComma=',';

        
/// <summary>
        
/// char 類型百分號
        
/// </summary>

        public const char ConstCharPercent='%';

        
/// <summary>
        
/// 發生權限訪問錯誤時,轉向的錯誤提示頁面
        
/// </summary>

        public const string ConstRoleErrorPageName="RoleError.aspx?Index=-1";
        
        
/// <summary>
        
/// DB的連接字符串
        
/// </summary>

        public const string  ConstWebConfigFileKeyName_ConnectionString="ConnectionString";
                
        
public Global()
        
{
            InitializeComponent();
        }
    
        
        
protected void Application_Start(Object sender, EventArgs e)
        
{
                        
        }

 
        
protected void Session_Start(Object sender, EventArgs e)
        
{
            
        }


        
protected void Application_BeginRequest(Object sender, EventArgs e)
        
{

        }


        
protected void Application_EndRequest(Object sender, EventArgs e)
        
{

        }


        
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
        
{
            
if (HttpContext.Current.User!=null)
            
{    
                
//用戶已經通過驗證
                if (Request.IsAuthenticated ) 
                
{
                    
//得到用戶的角色Cookie的名稱
                    string userRolesCookieName=FormsAuthentication.FormsCookieName;
                    
//得到用戶的角色Cookie
                    string currentCookieValue=Context.Request.Cookies[userRolesCookieName].Value;
                    
//解密
                    FormsAuthenticationTicket currentFormsAuthenticationTicket = FormsAuthentication.Decrypt(currentCookieValue);

                    
//得到cookie中的用戶數據
                    string[] userData = BCSTool.StringToArray(currentFormsAuthenticationTicket.UserData,ConstCharPercent);
                    
                    
//取得用戶的個人詳細信息數組                
                    int userId=Convert.ToInt32( userData[0]);
                    
string userDisPlayName=userData[1];
                    
string userName=userData[2];
                    
string userEmail=userData[3];
                    
                    
//按當初加入的規則分解爲數組
                    string [] roleArray= BCSTool.StringToArray(userData[4],ConstCharComma );

                    
//設置當前 HTTP 安全信息
                    Context.User = new BCSLoginPrincipal(userId,
                                                        userDisPlayName,
                                                        userName,
                                                        userEmail,
                                                        roleArray,
                                                        HttpContext.Current.User.Identity);
                }

            }

        }


        
protected void Application_Error(Object sender, EventArgs e)
        
{

        }


        
protected void Session_End(Object sender, EventArgs e)
        
{

        }


        
protected void Application_End(Object sender, EventArgs e)
        
{

        }

            
        
Web 窗體設計器生成的代碼
    }

}



讓我們再看類BCSLoginPrincipal
實現了接口:IPrincipal,該接口定義用戶對象的基本功能。
該接口有一個屬性IIdentity Identity {get;},獲取當前用戶的標識。
一個方法bool IsInRole(string role),確定當前用戶是否屬於指定的角色。
using System;
using System.Security.Principal;

namespace BluepieCustomerService
{
    
/// <summary>
    
/// BCSLoginPrincipal 的摘要說明。
    
/// </summary>

    public class BCSLoginPrincipal :System.Security.Principal.IPrincipal 
    
{
        
private string[] _userRole;
        
        
protected IIdentity _iIdentity;

        
int _userId;
        
string    _userDisPlayName;
        
string  _userName;
        
string  _userEmail;
        
        
/// <summary>
        
/// 類BCSLoginPrincipal的有參構造器
        
/// </summary>
        
/// <param name="iIdentity"></param>
        
/// <param name="userRole"></param>

        public BCSLoginPrincipal(int userId,string userDisPlayName,string userName,string userEmail    , string[] userRole,IIdentity iIdentity)
        
{
            
this._userId=userId;
            
this._userDisPlayName=userDisPlayName;
            
this._userName=userName;
            
this._userEmail=userEmail;
            
this._userRole=userRole;
            
this._iIdentity=iIdentity;
        }


        
/// <summary>
        
/// 取得和設置登陸用戶的UserID
        
/// </summary>

        public int UserId
        
{
            
get
            
{
                
return _userId;
            }

            
set
            
{
                _userId
=value;
            }

        }


        
/// <summary>
        
/// 取得和設置登陸用戶的登陸帳號
        
/// </summary>

        public string UserDisPlayName
        
{
            
get
            
{
                
return _userDisPlayName;
            }

            
set
            
{
                _userDisPlayName
=value;
            }

        }


        
/// <summary>
        
/// 取得和設置登陸用戶的真實姓名
        
/// </summary>

        public string UserName
        
{
            
get
            
{
                
return _userName;
            }

            
set
            
{
                _userName
=value;
            }

        }


        
/// <summary>
        
/// 取得和設置登陸用戶的Email
        
/// </summary>

        public string UserEmail
        
{
            
get
            
{
                
return _userEmail;
            }

            
set
            
{
                _userEmail
=value;
            }

        }


        
        
/// <summary>
        
/// 取得和設置登陸用戶的角色數組
        
/// </summary>

        public string[] UserRole
        
{
            
get 
            
{
                
return _userRole;
            }

            
set 
            
{
                _userRole 
= value; 
            }

        }


        
public IIdentity Identity
        
{
            
get    
            
{
                
return _iIdentity;
            }

            
set    
            
{
                _iIdentity 
= value; 
            }

        }


        
/// <summary>
        
/// 實現接口方法,判斷用戶的角色是否合法
        
/// </summary>
        
/// <param name="role"></param>
        
/// <returns></returns>

        public bool IsInRole(string role)
        
{
            
//用戶傳過來的角色字符串有可能包含多個角色,所以我們得先分解爲數組
            string [] roleArray = BCSTool.StringToArray(role,Global.ConstCharComma);
            
//取得數組長度
            int roleArrayLength=roleArray.Length;

            
//取出數組中每一個角色與用戶的現有角色做比較
            for(int i=0;i<roleArrayLength;i++)
            
{
                
if( isRole( roleArray[i] ) )
                
{
                    
return true;
                }

            }

            
return false;
        }


        
/// <summary>
        
/// 與用戶的現有角色做比較
        
/// </summary>
        
/// <param name="str"></param>
        
/// <returns></returns>

        bool isRole(string str)
        
{
            
int arrayLength=_userRole.Length;

            
for(int i=0;i<arrayLength;i++)
            
{
                
if ( _userRole[i]==str )
                
{
                    
return true;
                }

            }

            
return false;
        }


    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章