日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在Silverlight+WCF中应用以角色为基础的安全模式(一)基础篇之角色为基础的安全模式简介...

發(fā)布時間:2024/4/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Silverlight+WCF中应用以角色为基础的安全模式(一)基础篇之角色为基础的安全模式简介... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  

??? 引言

  最近一直在研究Silverlight+WCF應(yīng)用中的安全問題,如何設(shè)計一個安全,又符合Silverlight和WCF的規(guī)范的應(yīng)用呢?又可以將以前的角色為基礎(chǔ)的開發(fā)框架拿來主義呢?

  我們知道WCF在安全方面提供了很多的綁定協(xié)議,可是Silverlight3+WCF的話,只有basicHttpBinding可以使用,這就使得我們的選擇不多,還有就是項目本身是一個互聯(lián)網(wǎng)應(yīng)用,還是使用比較通用的角色為基礎(chǔ)的權(quán)限系統(tǒng)比較好。

  這個系列有兩篇文章,一篇講解.NET框架提供我們的角色為基礎(chǔ)的安全模式,以及如何根據(jù)我們的需求,自定義角色為基礎(chǔ)的安全模式;一篇講解在Silverlight+WCF應(yīng)用中,如何設(shè)計的一種角色為基礎(chǔ)的應(yīng)用方法。

  文中的代碼下載:/Files/virusswb/RetrieveSecurity_src.zip

  正文

  

?

  .NET中的角色為基礎(chǔ)的安全

  .NET 框架使得 你在應(yīng)用中實現(xiàn)以角色為基礎(chǔ)的安全模式非常容易。迫使安全有兩部分組成,認(rèn)證和授權(quán)。認(rèn)證就是驗證你的身份。應(yīng)用程序驗證你就是你所聲明的人。通常的做法是用戶輸入用戶名和密碼,應(yīng)用查找你輸入的用戶名,然后驗證你輸入的密碼是否匹配。更高級的做法是依賴生物認(rèn)證,例如:指紋或者是視網(wǎng)膜,又或者是一張綁定了個人PIN碼的認(rèn)證卡。如果認(rèn)證失敗,用戶將不被允許進(jìn)入系統(tǒng),除非系統(tǒng)允許匿名訪問,意味著如果系統(tǒng)確認(rèn)了你的身份,就授予你訪問權(quán)。授權(quán)就是確認(rèn)用戶是否能操作系統(tǒng)的某項功能。授權(quán)依賴于已知的用戶身份以及和用戶相關(guān)的安全信息,基于這些安全信息,系統(tǒng)就可以批準(zhǔn)或者拒絕用戶的請求。

  .NET框架提供了通過Identity訪問用戶信息,通過principal訪問授權(quán)信息。Thread.CurrentPrincipal提供了當(dāng)前線程的principal信息,默認(rèn)情況下,它是一個非認(rèn)證的授權(quán)。框架提供了兩種不同的principal,一個是windows principal,一個是通用的授權(quán)generic principalWindows principal工作在windows 操作系統(tǒng)上。所以,當(dāng)前運(yùn)行的線程會映射到一個windows帳戶上。如果你正在運(yùn)行一個windows form的應(yīng)用程序,它就是一個用戶。

有兩個辦法可以訪問windows principal

// set that a principal should be attached to the thread and

// it should be a windows principal

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

// get hold of the windows principal

WindowsPrincipal MyPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;

// get the windows identity

WindowsIdentity MyIdentity = MyPrincipal.Identity;

?

  通過調(diào)用當(dāng)前程序域的SetPrincipalPolicy,你告訴框架當(dāng)前線程需要附加的principal,你需要在第一次訪問principal之前做這些設(shè)置。調(diào)用Thread.CurrentPrincipal返回和當(dāng)前線程綁定的principal。第一次這么做的時候,框架會查詢windows的帳戶信息創(chuàng)建一個windows身份和一個windows授權(quán)并且綁定到這個線程。從windows principal你可以訪問windows identity。另一個辦法是

// get an identity object for the windows user

WindowsIdentity Identity = WindowsIdentity.GetCurrent();

// get hold of the windows principal

WindowsPrincipal MyPrincipal = new WindowsPrincipal(Identity);

  WindowsIdentity.GetCurrent()查詢windows帳戶信息,同時創(chuàng)建一個identity代表當(dāng)前用戶,那樣你可以用這個identity創(chuàng)建一個principal。這    樣做的缺點(diǎn)就是每次都需要查詢windows帳戶,然后創(chuàng)建一個identity和一個principal。第一種方法每次都會使用相同的identityprincipal。通用的principal允許你創(chuàng)建不綁定任何windows帳戶的一個principalidentity

// create the generic identity GenericIdentity

Identity = new GenericIdentity("Administrator");

// define the roles to associate with the generic principal

string[] Roles = new string[2] { "Manager", "Architect" };

// create the generic principal

GenericPrincipal MyPrincipal = new GenericPrincipal(Identity,Roles);

// bind the generic principal to the thread

Thread.CurrentPrincipal = MyPrincipal;

  首先創(chuàng)建一個通用的identity,你需要提供identity的名稱,因為他不綁定任何windows帳戶,需要一個用戶名。然后定義你想要這個授權(quán)擁有的角色,最后創(chuàng)建一個principal,然后提供identity和角色列表。然后你可以將這個授權(quán)綁定到當(dāng)前線程。

創(chuàng)建自定義的授權(quán)principal和認(rèn)證identity

  .NET框架允許通過實現(xiàn)IPrincipalIIdentity接口,來自定義授權(quán)和認(rèn)證。本文下面的代碼,將展示如何創(chuàng)建一個數(shù)據(jù)庫驅(qū)動的認(rèn)證和授權(quán)。

  

  授權(quán)過程在用戶表中檢查提供的用戶名和密碼。授權(quán)成功之后,讀取用戶信息和用戶的安全組信息,查看用戶屬于那些安全組。

  這些信息對于自定義認(rèn)證和授權(quán)都是必要的。但是授權(quán)還可以更進(jìn)一步,還可以檢查個人權(quán)限信息,例如:用戶是否被允許查看預(yù)算等。這些信息都是從SecurityRightAssign表中讀取出來,讓我們先創(chuàng)建一個自定義身份。

public class UserIdentity : IIdentity

{

// the authentication type for us is always database

private static string AuthenticationTypeString = "Database";

// hash table with all the user info we have

private Hashtable UserInfo;

// create the user identity; all user information is in the hashtable passed along

private UserIdentity(Hashtable UserInfo)

{

????? this.UserInfo = UserInfo;

}

//create a user identity and return it to the caller

public static UserIdentity CreateUserIdentity(Hashtable UserInfo)

{

????? return new UserIdentity(UserInfo);

}

}

?

  UserIdentity實現(xiàn)了IIdentity接口,需要我們事先三個屬性。類型的構(gòu)造函數(shù)被私有化,防止通過實例化來構(gòu)造對象。你需要通過靜態(tài)方法CreateUserIdentity,傳遞一個HashTable結(jié)構(gòu)的用戶類型,然后創(chuàng)建一個身份的實例。Name屬性返回這個身份的名稱。

// returns the name of the identity

public string Name

{

? get

? {

??? return

??? Convert.ToString(UserInfo[UserNameKey],CultureInfo.InvariantCulture).Trim();

? }

}

// returns if identity is authenticated or not

public bool IsAuthenticated

{

? get

? {

??? return true;

? }

}

// the type of authentication

public string AuthenticationType

{

? get

? {

??? return AuthenticationTypeString;

? }

}

  IsAuthenticated屬性返回用戶是否被認(rèn)證通過,在上面的代碼中用戶總是被認(rèn)證功過,因為我們return true。如果你允許匿名訪問,你就可以為匿名用戶設(shè)置為false。最后一個屬性AuthenticationType返回的是驗證的類型,在我們的代碼中返回的是“Database”。WindowsIdentity返回的是NTLMGenericIdentity返回的是空字符串或者是實例化GenericIdentity的時候傳遞的驗證類型。下面,我們里實現(xiàn)自定義的principal

public class SecurityPrincipal : IPrincipal

{

// stores the list of security rights the user belongs too

private Hashtable SecurityGroups;

// stores the list of security rights the user has

private Hashtable SecurityRights;

// the user identity we create and associate with this principal

private UserIdentity TheUserIdentity;

// constructor: stores role and permission info and creates custom identity

private SecurityPrincipal(Hashtable SecurityGroups, Hashtable SecurityRights,

????????????????? Hashtable UserInfo)

{

????? this.SecurityGroups = SecurityGroups;

????? this.SecurityRights = SecurityRights;

????? // creates the IIdentity for the user and associates it with this IPrincipal

????? TheUserIdentity = UserIdentity.CreateUserIdentity(UserInfo);

}

// create the security principal and return it to the caller

public static SecurityPrincipal CreateSecurityPrincipal(Hashtable SecurityGroups,

????????????????? Hashtable SecurityRights, Hashtable UserInfo)

{

????? return new SecurityPrincipal(SecurityGroups,SecurityRights,UserInfo);

}

}

  實現(xiàn)IPrincipal接口需要實現(xiàn)Identity屬性和IsInRole()方法,同樣的這個類型的構(gòu)造函數(shù)也是私有的,防止通過實例化來創(chuàng)建對象。你需要調(diào)用靜態(tài)方法CreateSecurityPrincipal,傳遞一個hashtable類型的用戶信息,一個用戶所屬的角色信息,還有就是用戶在系統(tǒng)中的特權(quán)。這個類型的構(gòu)造函數(shù)調(diào)用自定義的Identity方法的靜態(tài)函數(shù)CreateUserIdentity,將用戶信息傳遞給CreateUserIdentity方法,然后返回一個UserIdentityCreateSecurityPrincipal方法返回一個自定義的principal實例。Identity屬性返回和這個principal相關(guān)聯(lián)的identity

// returns the Identity object associated with the principal

public IIdentity Identity

{

????? get

????? {

??????????? return TheUserIdentity;

????? }

}

// checks if user belongs to role

public bool IsInRole(string Role)

{

????? return SecurityGroups.ContainsValue(Role);

}

// checks if user has permission

public bool HasPermission(string Permission)

{

????? return SecurityRights.ContainsValue(Permission);

}

  IsInRole方法檢查用戶是否屬于角色,是通過檢查角色是否在hashtable類型的SecurityGroups中,然后返回true 或者false。我們自定義的principal還實現(xiàn)了一個方法HasPermission,它和IsInRole方法類似,但是檢查的是提供的權(quán)限是否在特權(quán)列表中,然后返回true或者false

這些已經(jīng)實現(xiàn)了自定義的identityprincipal,下面的代碼解釋了信息是如何從數(shù)據(jù)庫中讀取,最后要做的就是去使用它。

public static IPrincipal SetSecurityPrincipal(Hashtable SecurityGroups,

?????????????????????????????? Hashtable SecurityRights, Hashtable UserInfo)

{

// set that we want to use authentication within the current app-domain;

// this means a thread will have a IPrincipal associated which is then

// used by the .NET security classes when checking role based security

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

// we switch to the new security principal only if we didn't do so already;

// protects us from the client calling the method multiple times

if (!(Thread.CurrentPrincipal is SecurityPrincipal))

{

? // create a new instance of the security principal which we can do only

? // within a class member as we marked the constructor private

? SecurityPrincipal TheSecurityPrincipal = new SecurityPrincipal(SecurityGroups,

????????????????? SecurityRights,UserInfo);

? // get a reference to the current security principal so the caller

? //can keep hold of it

? IPrincipal CurrentSecurityPrincipal = Thread.CurrentPrincipal;

? // set the security principal for the executing thread to the newly created one

? Thread.CurrentPrincipal = TheSecurityPrincipal;

? // return the current security principal;

? return CurrentSecurityPrincipal;

}

// return null if we don't switch the security principal

else

????? return null;

}

為了使用,我們在SecurityPrincipal類型上提供了一個靜態(tài)方法SetSecurityPrincipal。首先調(diào)用AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

  這樣做看起來是錯誤的,因為我們想要的不是一個windows principal,而是一個自定義的principal。這么做只是為了保證我們擁有一個綁定到當(dāng)前線程的principal,然后我們檢查綁定到當(dāng)前線程的principal是否是自定義的principal類型。如果是的話,我們什么都不需要做,因為我們已經(jīng)為當(dāng)前線程分配了我們自定義的principal,這確保了調(diào)用者在多線程的環(huán)境中調(diào)用不會產(chǎn)生負(fù)面的問題。只是在第一次我們會發(fā)現(xiàn)沒有綁定到自定義的principal,這時候我們創(chuàng)建自定義的principal,創(chuàng)建自定義的identity,并且綁定到當(dāng)前線程。如果調(diào)用者需要的話,我們返回當(dāng)前principal給他。

  在使用Thread.CurrentPrincipal訪問用戶信息的時候,會檢查用戶的角色和特權(quán),這些都可以通過在principal上調(diào)用IsInRole或者是訪問identity來實現(xiàn)。如果你想檢查用戶的特權(quán),你可以使用從Thread.CurrentPrincipal中獲取的principalHasPermission方法來實現(xiàn)。

public bool CheckSecurityPermission(string Permission)

{

????? // if the current IPrincipal is of the same type as our custom

????? // security principal then go and check the security right

????? if (Thread.CurrentPrincipal is SecurityPrincipal)

????? {

????????? SecurityPrincipal Principal = (SecurityPrincipal)

??????????????????????????????????????? Thread.CurrentPrincipal;

????????? // returns whether the user has the permission or not

????????? return Principal.HasPermission(Permission);

????? }

????? // if we have a standard IPrincipal in use then we can not check

????? // the permission and we always return false

????? else

????????? return false;

}

  如果你正在創(chuàng)建一個新的應(yīng)用程序域線程,你不想為每一個線程設(shè)置自定義的principal,你可以為每一個新創(chuàng)建的線程創(chuàng)建一個默認(rèn)的principal。設(shè)置默認(rèn)principal一定要在第一次第一次訪問principal之前設(shè)置Thread.CurrentPrincipal

// create the custom principal

SecurityPrincipal MyPrincipal = SecurityPrincipal.CreateSecurityPrincipal(

????????????????? AppDomain.CurrentDomain.SetThreadPrincipal);

// set the custom principal as the app domain policy

AppDomain.CurrentDomain.SetThreadPrincipal(MyPrincipal);

  你設(shè)置默認(rèn)principal,只需要在應(yīng)用程序域設(shè)置一次。在應(yīng)用程序域設(shè)置多次會引發(fā)PolicyException異常。

?

  示例代碼

?

  示例代碼演示的是一個windows form程序,首先需要用戶登錄(在數(shù)據(jù)庫中已經(jīng)有兩個用戶,virusswb,密碼和用戶名一致)。btnLogon_Click()事件和btnLogin按鈕關(guān)聯(lián),調(diào)用DataLayer.CheckUserNameAndPassword().用來驗證用戶,調(diào)用DataLayer.RetrieveUserInformation().來獲取用戶信息,最后通過調(diào)用DataLayer.RetrieveSecurityInformation().來獲取用戶所屬的角色和權(quán)限信息,在獲取了用戶信息、角色信息和權(quán)限信息之后,使用SecurityPrincipal.SetSecurityPrincipal()創(chuàng)建一個principalidentity,并且綁定到當(dāng)前線程。

  從示例中看出用戶屬于是三個角色,全部的權(quán)限,和用戶信息,可以檢查用戶是否屬于某一個角色,是否具有某一個權(quán)限,CheckSecurityRoles() and CheckSecurityPermissions()返回用戶是否屬于一個角色,是否有一個權(quán)限。logoff 按鈕的 LogOff_Click()方法恢復(fù)原始的principal,并且返回登陸界面,允許另外一個用戶登錄,繼續(xù)前面的處理過程。

  在示例文件夾中你會發(fā)現(xiàn)一個叫做RetrieveSecurity.bak的文件,它是數(shù)據(jù)庫的備份文件。恢復(fù)數(shù)據(jù)庫,配置app.config文件中的連接字符串。你可以在數(shù)據(jù)庫中添加用戶、角色和權(quán)限信息。示例展示了在.NET 的角色為基礎(chǔ)的安全模型之后,如何實現(xiàn)數(shù)據(jù)庫驅(qū)動的驗證和安全模型。

?

  總結(jié)

  大多數(shù)應(yīng)用都需要通過角色和權(quán)限來實現(xiàn)用戶驗證和安全模型。.NET框架使得這些變得容易,幾行代碼,就改變了windows賬號和安全組的影響。使用自定義的identityprincipal可以很容易的擴(kuò)展角色為基礎(chǔ)的安全框架,示例代碼展示的就是如何實現(xiàn)數(shù)據(jù)庫驅(qū)動的角色權(quán)限系統(tǒng)。

  參考文獻(xiàn)

  【1】Role-Based Security? Microsoft

  【2】Introduction to Role-Based Security in .NET? Klaus Salchner

  【3】在Identity 增加自己的屬性 部門,并且使用access mdb文件實現(xiàn)角色驗證? iHqq

?

  感謝上面這些機(jī)構(gòu)和作者的無私奉獻(xiàn)。

轉(zhuǎn)載于:https://www.cnblogs.com/virusswb/archive/2010/03/01/1675414.html

總結(jié)

以上是生活随笔為你收集整理的在Silverlight+WCF中应用以角色为基础的安全模式(一)基础篇之角色为基础的安全模式简介...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。