Поделиться через


Основные понятия безопасности

Примечание.

Эта статья относится к Windows.

Сведения о ASP.NET Core см. в Обзор ASP.NET Core Security.

.NET предлагает безопасность на основе ролей, чтобы помочь решить проблемы безопасности с мобильным кодом и обеспечить поддержку, которая позволяет компонентам определять, какие пользователи уполномочены делать.

Типобезопасность и безопасность

Типобезопасный код обращается только к расположениям памяти, к ним разрешен доступ. (Для этого обсуждения безопасность типов специально относится к безопасности типов памяти и не следует путать с безопасностью типов в более широком отношении.) Например, типобезопасный код не может считывать значения из частных полей другого объекта. Типы доступны только в четко определенных допустимых методах.

Во время JIT-компиляции необязательный процесс проверки анализирует метаданные и общий промежуточный язык (CIL) метода, который должен быть JIT-компилирован в машинный код, чтобы убедиться, что они являются типобезопасными. Этот процесс пропускается, если код имеет разрешение на обход проверки. Дополнительные сведения о проверке см. в управляемого процесса выполнения.

Хотя проверка безопасности типов не является обязательной для запуска управляемого кода, типобезопасность играет важную роль в изоляции сборки и обеспечении безопасности. Если код обладает типовой безопасностью, платформа CLR может полностью изолировать сборки друг от друга. Эта изоляция помогает гарантировать, что сборки не могут негативно повлиять друг на друга, и это повышает надежность приложения. Типобезопасные компоненты могут безопасно выполняться в одном процессе, даже если они являются доверенными на разных уровнях. Если код не является безопасным, нежелательные побочные эффекты могут возникать. Например, среда выполнения не может предотвратить выполнение управляемым кодом вызова внеуправляемого кода и совершения вредоносных операций. Если код является типобезопасным, механизм обеспечения безопасности среды выполнения гарантирует, что он не обращается к родному коду, если не имеет разрешения на это. Весь код, который не является типобезопасным, должен получить разрешение SecurityPermission с использованием переданного элемента перечисления SkipVerification для выполнения.

Примечание.

Безопасность доступа к коду (CAS) не рекомендуется использовать во всех версиях .NET Framework и .NET. Последние версии .NET не учитывают заметки CAS и создают ошибки, если используются API, связанные с CAS. Разработчики должны искать альтернативные средства выполнения задач безопасности.

Основной

Главный объект представляет идентичность и роль пользователя и действует от его имени. Безопасность на основе ролей в .NET поддерживает три типа субъектов:

  • Универсальные субъекты представляют пользователей и роли, которые существуют независимо от пользователей и ролей Windows.

  • Принципы Windows представляют собой пользователей Windows и их роли (или их группы Windows). Субъект Windows может олицетворить другого пользователя, что означает, что субъект может получить доступ к ресурсу от имени пользователя при показе удостоверения, принадлежащего этому пользователю.

  • Пользовательские субъекты могут определяться приложением любым способом, необходимым для этого конкретного приложения. Они могут расширить базовое понятие идентичности и ролей принципала.

Для получения дополнительной информации смотрите Основные и идентификационные объекты.

Аутентификация

Аутентификация — это процесс обнаружения и проверки личности объекта путем изучения учетных данных пользователя и их сверки с авторитетным источником. Сведения, полученные во время проверки подлинности, напрямую используются в вашем коде. Вы также можете использовать безопасность на основе ролей .NET для проверки подлинности текущего пользователя и определить, разрешать ли субъекту доступ к коду. Примеры проверки подлинности субъекта для определенных ролей см. в перегрузках метода WindowsPrincipal.IsInRole. Например, можно использовать перегрузку WindowsPrincipal.IsInRole(String), чтобы определить, является ли текущий пользователь членом группы "Администраторы".

Сегодня используются различные механизмы проверки подлинности, многие из которых можно использовать с безопасностью на основе ролей .NET. Некоторые из наиболее часто используемых механизмов являются базовыми, дайджест, Passport, механизмами операционной системы (например, NTLM или Kerberos) или механизмами, определяемыми приложением.

Пример

В следующем примере требуется, чтобы активный субъект был администратором. Параметр name есть null, что позволяет любому пользователю, который является администратором, удовлетворить требование.

Примечание.

В Windows Vista контроль учетных записей (UAC) определяет привилегии пользователя. Если вы являетесь членом встроенной группы "Администраторы", вы назначаете два маркера доступа во время выполнения: маркер доступа стандартного пользователя и маркер доступа администратора. По умолчанию вы находитесь в стандартной роли пользователя. Чтобы выполнить код, который требует от вас быть администратором, необходимо сначала повысить привилегии от стандартного пользователя к администратору. Это можно сделать при запуске приложения, щелкнув правой кнопкой мыши значок приложения и указав, что вы хотите запустить от имени администратора.

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

В следующем примере показано, как определить личность субъекта и доступные ему роли. Вы можете воспользоваться этим примером, чтобы подтвердить, что текущий пользователь находится в допустимой роли для использования вашего приложения.

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($"{roleName}: Could not obtain role for this RID.");
            }
        }
        // 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

Авторизация

Авторизация — это процесс определения того, разрешено ли субъекту выполнять запрошенное действие. Авторизация возникает после проверки подлинности и использует сведения о удостоверении и ролях субъекта, чтобы определить, к каким ресурсам может получить доступ субъект. Для реализации авторизации можно использовать безопасность на основе ролей .NET.

См. также