重要的安全性概念Key Security Concepts

Microsoft.NET Framework 提供以角色為基礎的安全性,以幫助解除對行動程式碼安全性的相關疑慮,並提供支援,讓元件能夠判斷哪些使用者有權執行。The Microsoft .NET Framework offers role-based security to help address security concerns about mobile code and to provide support that enables components to determine what users are authorized to do.

類型安全和安全性Type safety and security

類型安全程式碼只會存取經授權存取的記憶體位置。Type-safe code accesses only the memory locations it is authorized to access. (這裡所討論的類型安全是專指記憶體類型安全,不應與廣義的類型安全混淆。)例如,類型安全程式碼無法從另一個物件的私用欄位讀取值。(For this discussion, type safety specifically refers to memory type safety and should not be confused with type safety in a broader respect.) For example, type-safe code cannot read values from another object's private fields. 它只會以妥善定義、可允許的方式來存取類型。It accesses types only in well-defined, allowable ways.

在 Just-In-Time (JIT) 編譯期間,選擇性的驗證程序會檢查中繼資料,以及要以 JIT 編譯成原生機器程式碼之方法的 Microsoft Intermediate Language (MSIL),以驗證其類型安全。During just-in-time (JIT) compilation, an optional verification process examines the metadata and Microsoft intermediate language (MSIL) of a method to be JIT-compiled into native machine code to verify that they are type safe. 如果程式碼具有略過驗證的權限,則會略過此程序。This process is skipped if the code has permission to bypass verification. 如需有關驗證的詳細資訊,請參閱 Managed 執行程序For more information about verification, see Managed Execution Process.

雖然沒有強制要驗證類型安全才能執行 Managed 程式碼,但是在組件隔離和強制執行安全性的作業中,類型安全扮演相當重要的角色。Although verification of type safety is not mandatory to run managed code, type safety plays a crucial role in assembly isolation and security enforcement. 當程式碼類型安全時,Common Language Runtime 可以將組件彼此完全隔離。When code is type safe, the common language runtime can completely isolate assemblies from each other. 此隔離有助於確保組件無法對彼此產生不利的影響,而且也會增加應用程式的可靠性。This isolation helps ensure that assemblies cannot adversely affect each other and it increases application reliability. 類型安全元件即使受信任的層級不同,還是可以在相同的處理序中安全地執行。Type-safe components can execute safely in the same process even if they are trusted at different levels. 當程式碼不是類型安全時,可能會發生不必要的副作用。When code is not type safe, unwanted side effects can occur. 例如,執行階段無法防止 Managed 程式碼呼叫機器碼 (Unmanaged) 及執行惡意的作業。For example, the runtime cannot prevent managed code from calling into native (unmanaged) code and performing malicious operations. 當程式碼為類型安全時,執行階段的安全性強制機制可確保它不會存取原生程式碼,除非它有這樣的權限。When code is type safe, the runtime's security enforcement mechanism ensures that it does not access native code unless it has permission to do so. 所有不是類型安全的程式碼,都必須被授與具有通過之列舉成員 SkipVerificationSecurityPermission,才能執行。All code that is not type safe must have been granted SecurityPermission with the passed enum member SkipVerification to run.

如需詳細資訊,請參閱程式碼存取安全性基本概念For more information, see Code Access Security Basics.

主體Principal

主體代表使用者的身分識別與角色,並且會代表使用者採取行動。A principal represents the identity and role of a user and acts on the user's behalf. 在 .NET Framework 中,以角色為基礎的安全性可支援三種主體:Role-based security in the .NET Framework supports three kinds of principals:

  • 泛型主體代表獨立於 Windows 使用者和角色而存在的使用者和角色。Generic principals represent users and roles that exist independent of Windows users and roles.

  • Windows 主體代表 Windows 使用者及其角色 (或其 Windows 群組)。Windows principals represent Windows users and their roles (or their Windows groups). Windows 主體可以模擬另一位使用者,這表示該主體可以代表使用者存取資源,同時呈現屬於該使用者身分識別。A Windows principal can impersonate another user, which means that the principal can access a resource on a user's behalf while presenting the identity that belongs to that user.

  • 自訂主體可以由應用程式以該特定應用程式所需的任何方式來定義。Custom principals can be defined by an application in any way that is needed for that particular application. 其可擴充主體身分識別和角色的基本概念。They can extend the basic notion of the principal's identity and roles.

如需詳細資訊,請參閱主體和身分識別物件For more information, see Principal and Identity Objects.

驗證Authentication

驗證是探索並確認主體身分識別的程序,它會檢查使用者的認證,並針對某授權單位來驗證那些認證。Authentication is the process of discovering and verifying the identity of a principal by examining the user's credentials and validating those credentials against some authority. 在驗證期間取得的資訊可直接供是由您的程式碼使用。The information obtained during authentication is directly usable by your code. 您也可以使用 .NET Framework 以角色為基礎的安全性來驗證目前使用者,以及判斷是否允許該主體存取您的程式碼。You can also use .NET Framework role-based security to authenticate the current user and to determine whether to allow that principal to access your code. 請參閱 WindowsPrincipal.IsInRole 方法的多載,以取得如何針對特定角色來驗證主體的範例。See the overloads of the WindowsPrincipal.IsInRole method for examples of how to authenticate the principal for specific roles. 例如,您可以使用 WindowsPrincipal.IsInRole(String) 多載來判斷目前使用者是否為系統管理員群組的成員。For example, you can use the WindowsPrincipal.IsInRole(String) overload to determine if the current user is a member of the Administrators group.

當今所使用的驗證機制非常多樣化,其中有許多可以搭配 .NET Framework 以角色為基礎的安全性。A variety of authentication mechanisms are used today, many of which can be used with .NET Framework role-based security. 部分最常用的機制有基本、摘要式、Passport、作業系統 (例如 NTLM 或 Kerberos) 或應用程式定義的機制。Some of the most commonly used mechanisms are basic, digest, Passport, operating system (such as NTLM or Kerberos), or application-defined mechanisms.

範例Example

下列範例需要由作用中的主體做為系統管理員。The following example requires that the active principal be an administrator. name 參數為 null,可讓做為系統管理員的任何使用者傳遞要求。The name parameter is null, which allows any user who is an administrator to pass the demand.

注意

在 Windows Vista 中,使用者帳戶控制 (UAC) 會判斷使用者的權限。In Windows Vista, User Account Control (UAC) determines the privileges of a user. 如果您是內建 Administrators 群組的成員,系統會將兩個執行階段存取語彙基元 (Token) 指派給您:標準使用者存取語彙基元及管理員存取語彙基元。If you are a member of the Built-in Administrators group, you are assigned two run-time access tokens: a standard user access token and an administrator access token. 根據預設,您會屬於標準使用者角色。By default, you are in the standard user role. 若要執行需要您是系統管理員的程式碼,您必須先將權限從標準使用者提高為系統管理員。To execute the code that requires you to be an administrator, you must first elevate your privileges from standard user to administrator. 您可以在啟動應用程式時,以滑鼠右鍵按一下應用程式圖示,並指出您想要以系統管理員身分執行,藉此提高為系統管理員權限。You can do this when you start an application by right-clicking the application icon and indicating that you want to run as an administrator.

using namespace System;
using namespace System::Security;
using namespace System::Security::Permissions;
using namespace System::Security::Policy;
using namespace System::Security::Principal;

int main(array<System::String ^> ^args)
{
    System::String^ null;
    AppDomain::CurrentDomain->SetPrincipalPolicy(PrincipalPolicy::WindowsPrincipal);
    PrincipalPermission^ principalPerm = gcnew PrincipalPermission(null, "Administrators" );
      principalPerm->Demand();
      Console::WriteLine("Demand succeeded");
    return 0;
}
using System;
using System.Threading;
using System.Security.Permissions;
using System.Security.Principal;

class SecurityPrincipalDemo
{

    public static void Main()
    {
        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
        PrincipalPermission principalPerm = new PrincipalPermission(null, "Administrators");
        principalPerm.Demand();
        Console.WriteLine("Demand succeeded.");
    }
}
Imports System.Threading
Imports System.Security.Permissions
Imports System.Security.Principal



Class SecurityPrincipalDemo


    Public Shared Sub Main()
        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
        Dim principalPerm As New PrincipalPermission(Nothing, "Administrators")
        principalPerm.Demand()
        Console.WriteLine("Demand succeeded.")

    End Sub
End Class

下列範例示範如何判斷主體的身分識別,以及可供主體使用的角色。The following example demonstrates how to determine the identity of the principal and the roles available to the principal. 此範例的應用程式可能是要確認目前的使用者是您允許使用您的應用程式的角色。An application of this example might be to confirm that the current user is in a role you allow for using your application.

public:
   static void DemonstrateWindowsBuiltInRoleEnum()
   {
      AppDomain^ myDomain = Thread::GetDomain();

      myDomain->SetPrincipalPolicy( PrincipalPolicy::WindowsPrincipal );
      WindowsPrincipal^ myPrincipal = dynamic_cast<WindowsPrincipal^>(Thread::CurrentPrincipal);

      Console::WriteLine( "{0} belongs to: ", myPrincipal->Identity->Name );

      Array^ wbirFields = Enum::GetValues( WindowsBuiltInRole::typeid );

      for each ( Object^ roleName in wbirFields )
      {
         try
         {
            Console::WriteLine( "{0}? {1}.", roleName,
               myPrincipal->IsInRole(  *dynamic_cast<WindowsBuiltInRole^>(roleName) ) );
         }
         catch ( Exception^ ) 
         {
            Console::WriteLine( "{0}: Could not obtain role for this RID.",
               roleName );
         }
      }
   }
using System;
using System.Threading;
using System.Security.Permissions;
using System.Security.Principal;

class SecurityPrincipalDemo
{
    public static void DemonstrateWindowsBuiltInRoleEnum()
    {
        AppDomain myDomain = Thread.GetDomain();

        myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
        WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
        Console.WriteLine("{0} belongs to: ", myPrincipal.Identity.Name.ToString());
        Array wbirFields = Enum.GetValues(typeof(WindowsBuiltInRole));
        foreach (object roleName in wbirFields)
        {
            try
            {
                // Cast the role name to a RID represented by the WindowsBuildInRole value.
                Console.WriteLine("{0}? {1}.", roleName,
                    myPrincipal.IsInRole((WindowsBuiltInRole)roleName));
                Console.WriteLine("The RID for this role is: " + ((int)roleName).ToString());

            }
            catch (Exception)
            {
                Console.WriteLine("{0}: Could not obtain role for this RID.",
                    roleName);
            }
        }
        // Get the role using the string value of the role.
        Console.WriteLine("{0}? {1}.", "Administrators",
            myPrincipal.IsInRole("BUILTIN\\" + "Administrators"));
        Console.WriteLine("{0}? {1}.", "Users",
            myPrincipal.IsInRole("BUILTIN\\" + "Users"));
        // Get the role using the WindowsBuiltInRole enumeration value.
        Console.WriteLine("{0}? {1}.", WindowsBuiltInRole.Administrator,
           myPrincipal.IsInRole(WindowsBuiltInRole.Administrator));
        // Get the role using the WellKnownSidType.
        SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
        Console.WriteLine("WellKnownSidType BuiltinAdministratorsSid  {0}? {1}.", sid.Value, myPrincipal.IsInRole(sid));
    }

    public static void Main()
    {
        DemonstrateWindowsBuiltInRoleEnum();
    }
}
Imports System.Threading
Imports System.Security.Permissions
Imports System.Security.Principal

Class SecurityPrincipalDemo

    Public Shared Sub DemonstrateWindowsBuiltInRoleEnum()
        Dim myDomain As AppDomain = Thread.GetDomain()

        myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
        Dim myPrincipal As WindowsPrincipal = CType(Thread.CurrentPrincipal, WindowsPrincipal)
        Console.WriteLine("{0} belongs to: ", myPrincipal.Identity.Name.ToString())
        Dim wbirFields As Array = [Enum].GetValues(GetType(WindowsBuiltInRole))
        Dim roleName As Object
        For Each roleName In wbirFields
            Try
                ' Cast the role name to a RID represented by the WindowsBuildInRole value.
                Console.WriteLine("{0}? {1}.", roleName, myPrincipal.IsInRole(CType(roleName, WindowsBuiltInRole)))
                Console.WriteLine("The RID for this role is: " + Fix(roleName).ToString())

            Catch
                Console.WriteLine("{0}: Could not obtain role for this RID.", roleName)
            End Try
        Next roleName
        ' Get the role using the string value of the role.
        Console.WriteLine("{0}? {1}.", "Administrators", myPrincipal.IsInRole("BUILTIN\" + "Administrators"))
        Console.WriteLine("{0}? {1}.", "Users", myPrincipal.IsInRole("BUILTIN\" + "Users"))
        ' Get the role using the WindowsBuiltInRole enumeration value.
        Console.WriteLine("{0}? {1}.", WindowsBuiltInRole.Administrator, myPrincipal.IsInRole(WindowsBuiltInRole.Administrator))
        ' Get the role using the WellKnownSidType.
        Dim sid As New SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, Nothing)
        Console.WriteLine("WellKnownSidType BuiltinAdministratorsSid  {0}? {1}.", sid.Value, myPrincipal.IsInRole(sid))

    End Sub

    Public Shared Sub Main()
        DemonstrateWindowsBuiltInRoleEnum()

    End Sub
End Class

AuthorizationAuthorization

授權是決定是否允許主體執行所要求動作的程序。Authorization is the process of determining whether a principal is allowed to perform a requested action. 授權會在驗證之後進行,它會使用主體的身分識別和角色相關資訊來判斷主體可以存取哪些資源。Authorization occurs after authentication and uses information about the principal's identity and roles to determine what resources the principal can access. 您可以使用 .NET Framework 以角色為基礎的安全性來實作授權。You can use .NET Framework role-based security to implement authorization.