CodeAccessPermission 繼承自 IPermission。
做權限驗證工作的是 IPermission 接口的實現類,在CLR驗證權限的時候會調用 IPermission 的 Demand() 方法。
IPermission 接口類的對象由 CodeAccessSecurityAttribute 實現類對象的 CreatePermission() 方法生成;
CreatePermission() 方法使用了工廠模式,用戶可以在方法中返回一個實現了 IPermission 接口的類對象。
CodeAccessSecurityAttribute 和 CodeAccessPermission 都是抽象類,不能用來生成對象,用戶必須定義自己的繼承類來實現。
編譯器發現標記了 CodeAccessSecurityAttribute 的方法時,有以下幾個處理步驟:
1.編譯器掃描源代碼,找出 CodeAccessSecurityAttribute 類型的特性;
2.編譯器創建特性對象,並用源代碼中特性標籤所指定的屬性值給特性對象賦值;
3.編譯器調用特性對象的 CreatePermission() 方法,創建一個權限對象,將特性信息傳遞給它,然後將對象返回給編譯器;
4.編譯器調用權限對象的 ToXml() 方法,獲得一個SecurityElement對象;
5.編譯器將 ToXml() 方法返回的對象轉化爲 XML 數據並存入應用的元數據。
在程序的執行期內,當CLR發現權限集信息後,它首先會使用其中的類型信息創建一個權限對象,然後CLR會調用權限對象的FromXml()方
法,同時傳入方法元數據的XML數據,在權限對象屬性都被賦值後,CLR將調用它的Demand()方法。
[AttributeUsage(AttributeTargets.Assembly |
AttributeTargets.Class |
AttributeTargets.Struct |
AttributeTargets.Constructor |
AttributeTargets.Method,
AllowMultiple=true, Inherited=false)]
public abstract class CodeAccessSecurityAttribute : SecurityAttribute
{
// Constructors.
internal CodeAccessSecurityAttribute()
: base()
{
// Nothing to do here.
}
public CodeAccessSecurityAttribute(SecurityAction action)
: base(action)
{
// Nothing to do here.
}
}; // class CodeAccessSecurityAttribute
public interface IPermission : ISecurityEncodable
{
IPermission Copy();
IPermission Intersect(IPermission target);
IPermission Union(IPermission target);
bool IsSubsetOf(IPermission target);
[DynamicSecurityMethodAttribute()]
void Demand();
}
public abstract class CodeAccessPermission : IPermission
{
// Constructor.
protected CodeAccessPermission() {}
// Assert permissions for the caller.
public void Assert()
{
if(!ClrSecurity.Assert(this, 1))
{
throw new SecurityException
(_("Exception_SecurityNotGranted"));
}
}
// Deny permissions to the caller.
public void Deny()
{
ClrSecurity.Deny(this, 1);
}
// Convert this object into a string.
public override String ToString()
{
return ToXml().ToString();
}
// Convert an XML value into a permissions value.
public abstract void FromXml(SecurityElement elem);
// Convert this permissions object into an XML value.
public abstract SecurityElement ToXml();
// Implement the IPermission interface.
public abstract IPermission Copy();
public void Demand()
{
if(!ClrSecurity.Demand(this, 1))
{
throw new SecurityException
(_("Exception_SecurityNotGranted"));
}
}
public abstract IPermission Intersect(IPermission target);
public abstract bool IsSubsetOf(IPermission target);
public virtual IPermission Union(IPermission target)
{
return null;
}
}; // class CodeAccessPermission