Schlüsselbegriffe der Sicherheit

Hinweis

Dieser Artikel gilt für Windows

Informationen zu ASP.NET Core finden Sie unter Übersicht über ASP.NET Core-Sicherheit.

.NET bietet rollenbasierte Sicherheit, um Sicherheitsprobleme bei mobilem Code zu beheben und Komponenten die Möglichkeit einzuräumen, die Berechtigungen von Benutzern zu überprüfen.

Typsicherheit und Sicherheit

Typsicherer Code greift nur auf die Speicheradressen zu, für die er über die erforderliche Berechtigung verfügt. (Typsicherheit bezieht sich in diesem Zusammenhang auf die Typsicherheit für den Speicher, nicht zu verwechseln mit der allgemeinen Typsicherheit.) Typsicherer Code kann z. B. keine Werte aus den privaten Feldern eines anderen Objekts lesen. Der Zugriff auf Typen ist genau definiert und muss zulässig sein.

Während der JIT-Kompilierung (Just-In-Time) werden die Metadaten und MSIL (Microsoft Intermediate Language) einer Methode, die in systemeigenen Code des Computers JIT-kompiliert werden soll, in einem optionalen Prüfungsvorgang auf ihre Typsicherheit überprüft. Dieser Vorgang wird übersprungen, wenn der Code über die Berechtigung zum Umgehen der Überprüfung verfügt. Weitere Informationen über Überprüfung finden Sie unter Der verwaltete Ausführungsprozess.

Obwohl die Überprüfung der Typsicherheit für das Ausführen von verwaltetem Code nicht zwingend erforderlich ist, spielt die Typsicherheit eine wesentliche Rolle bei der Isolation von Assemblys und der Gewährleistung von Sicherheit. Wenn Code typsicher ist, kann die Common Language Runtime Assemblys vollständig voneinander isolieren. Diese Isolation trägt dazu bei, dass Assemblys einander nicht beeinträchtigen, und erhöht gleichzeitig die Zuverlässigkeit von Anwendungen. Typsichere Komponenten können ohne Sicherheitseinbußen in demselben Prozess ausgeführt werden, selbst wenn sie unterschiedliche Vertrauensebenen aufweisen. Wenn Code nicht typsicher ist, können unerwünschte Nebeneffekte auftreten. So kann die Common Language Runtime z. B. nicht verhindern, dass verwalteter Code systemeigenen (d. h. nicht verwalteten) Code aufruft und schädliche Vorgänge ausführt. Bei typsicherem Code gewährleistet die Durchsetzung von Sicherheit durch die Laufzeit, dass dieser nur mit der entsprechenden Berechtigung auf nativen Code zugreifen kann. Zum Ausführen von nicht typsicherem Code muss die SecurityPermission mit dem übergebenen Enumerationsmember SkipVerification erteilt werden.

Hinweis

Die Codezugriffssicherheit (CAS, Code Access Security) ist in allen Versionen von .NET Framework und .NET veraltet. Aktuelle Versionen von .NET berücksichtigen keine CAS-Anmerkungen und erzeugen Fehler, wenn CAS-bezogene APIs verwendet werden. Entwickler*innen sollten alternative Mittel zum Ausführen von Sicherheitsaufgaben suchen.

Prinzipal

Ein Prinzipal stellt die Identität und die Rolle eines Benutzers dar und handelt stellvertretend für den Benutzer. Die rollenbasierte Sicherheit in .NET unterstützt drei Arten von Prinzipals:

  • Allgemeine Prinzipals stellen Benutzer und Rollen dar, die unabhängig von Benutzern und Rollen unter Windows vorhanden sind.

  • Windows-Prinzipals stellen Windows-Benutzer und ihre Rollen bzw. ihre Windows-Gruppen dar. Ein Windows-Prinzipal kann einen anderen Benutzer imitieren, d. h., der Prinzipal kann im Namen eines Benutzers auf eine Ressource zugreifen, wenn er die Identität dieses Benutzers darstellt.

  • Benutzerdefinierte Prinzipals können von einer Anwendung je nach Bedarf beliebig definiert werden. Sie können die grundlegenden Eigenschaften der Identität und der Rollen des Prinzipals erweitern.

Weitere Informationen finden Sie unter Prinzipal- und Identitätsobjekte.

Authentifizierung

Bei der Authentifizierung wird die Identität eines Prinzipals anhand der Anmeldeinformationen des Benutzers abgerufen und überprüft. Anschließend wird die Gültigkeit dieser Anmeldeinformationen mithilfe einer autorisierten Stelle überprüft. Die bei der Authentifizierung abgerufenen Informationen können vom Code direkt verwendet werden. Sie können den aktuellen Benutzer auch mit der rollenbasierten Sicherheit von .NET authentifizieren und festlegen, ob der Prinzipal auf Ihren Code zugreifen kann. Beispiele zur Authentifizierung des Prinzipals für bestimmte Rollen finden Sie in den Überladungen der WindowsPrincipal.IsInRole-Methode. Sie können z. B. mit der WindowsPrincipal.IsInRole(String)-Überladung ermitteln, ob der aktuelle Benutzer Mitglied der Administratorgruppe ist.

Derzeit werden verschiedene Authentifizierungsverfahren eingesetzt, von denen viele mit der rollenbasierten Sicherheit in .NET verwendet werden können. Am häufigsten werden Standard-, Digest-, Passport- und Betriebssystemverfahren (z. B. NTLM oder Kerberos) sowie anwendungsdefinierte Verfahren verwendet.

Beispiel

Im folgenden Beispiel muss der aktive Prinzipal ein Administrator sein. Der name-Parameter ist null, sodass die Anforderung von allen Benutzern übergeben werden kann, die Administratoren sind.

Hinweis

Unter Windows Vista werden die Berechtigungen eines Benutzers über die Benutzerkontensteuerung (User Account Control, UAC) bestimmt. Als Mitglied der integrierten Administratorgruppe sind Ihnen zwei Zugriffstoken für die Laufzeit zugewiesen: ein Standardbenutzertoken und ein Administratorzugriffstoken. Standardmäßig verwenden Sie die Standardbenutzerrolle. Um Code ausführen zu können, der Administratorberechtigungen erfordert, müssen Sie zuerst Ihre Berechtigungen von Standardbenutzer auf Administrator erhöhen. Dazu starten Sie eine Anwendung, indem Sie mit der rechten Maustaste auf das Anwendungssymbol klicken und angeben, dass Sie die Anwendung als Administrator ausführen möchten.

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

Im folgenden Beispiel wird veranschaulicht, wie die Identität des Prinzipals sowie der Rollen bestimmt wird, die für den Prinzipal verfügbar sind. Eine Anwendungsmöglichkeit für dieses Beispiel könnte darin bestehen, zu überprüfen, ob die Rolle des aktuellen Benutzers für die Verwendung der Anwendung zulässig ist.

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

Autorisierung

Bei der Autorisierung wird bestimmt, ob das Ausführen einer angeforderten Aktion durch einen Prinzipal zulässig ist. Die Autorisierung findet nach der Authentifizierung statt. Sie bestimmt anhand der Informationen zur Identität und Rollen des Prinzipals, auf welche Ressourcen dieser zugreifen darf. Autorisierung können Sie in .NET mithilfe der rollenbasierten Sicherheit implementieren.

Weitere Informationen