PrincipalPermissionMode PrincipalPermissionMode PrincipalPermissionMode PrincipalPermissionMode Enum

Определение

Задает режим проверки авторизации при использовании PrincipalPermissionAttribute для управления доступом к методу.Sets the mode for authorization checks when using the PrincipalPermissionAttribute to control access to a method.

public enum class PrincipalPermissionMode
public enum PrincipalPermissionMode
type PrincipalPermissionMode = 
Public Enum PrincipalPermissionMode
Наследование
PrincipalPermissionModePrincipalPermissionModePrincipalPermissionModePrincipalPermissionMode

Поля

Always Always Always Always 4

Всегда позволяет пользователю указать класс IPrincipal для CurrentPrincipal.Always enables the user to specify a IPrincipal class for CurrentPrincipal.

Custom Custom Custom Custom 3

Позволяет пользователю указать настраиваемый класс IPrincipal для CurrentPrincipal.Enables the user to specify a custom IPrincipal class for CurrentPrincipal.

None None None None 0

CurrentPrincipal не задано.CurrentPrincipal is not set.

UseAspNetRoles UseAspNetRoles UseAspNetRoles UseAspNetRoles 2

CurrentPrincipal задан на основе поставщика ролей ASP.NETASP.NET (RoleProvider).CurrentPrincipal is set based on the ASP.NETASP.NET role provider (RoleProvider).

UseWindowsGroups UseWindowsGroups UseWindowsGroups UseWindowsGroups 1

CurrentPrincipal задан на основе Windows WindowsPrincipal ().CurrentPrincipal is set based on Windows (WindowsPrincipal). Если идентификация пользователя не связана с учетной записью Windows, используется анонимный вход Windows.If the user identity is not associated with a Windows account, anonymous Windows is used.

Примеры

В следующем примере показано, как указать UseAspNetRoles.The following example shows how to specify UseAspNetRoles.

namespace TestPrincipalPermission
{
    class PrincipalPermissionModeWindows
    {
    
        [ServiceContract]
        interface ISecureService
        {
            [OperationContract]
            string Method1();
        }
                
        class SecureService : ISecureService
        {
            [PrincipalPermission(SecurityAction.Demand, Role = "everyone")]
            public string Method1()
            {
                return String.Format("Hello, \"{0}\"", Thread.CurrentPrincipal.Identity.Name);
            }
        }

        public void Run()
        {
            Uri serviceUri = new Uri(@"http://localhost:8006/Service");
            ServiceHost service = new ServiceHost(typeof(SecureService));
            service.AddServiceEndpoint(typeof(ISecureService), GetBinding(), serviceUri);
            service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles;
            service.Open();

            EndpointAddress sr = new EndpointAddress(
                serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name));
            ChannelFactory<ISecureService> cf = new ChannelFactory<ISecureService>(GetBinding(), sr);
            ISecureService client = cf.CreateChannel();
            Console.WriteLine("Client received response from Method1: {0}", client.Method1());
            ((IChannel)client).Close();
            Console.ReadLine();
            service.Close();
            
        }

        public static Binding GetBinding()
        {
            WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
            binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
            return binding;
        }
    }
}
Namespace TestPrincipalPermission
	Friend Class PrincipalPermissionModeWindows

		<ServiceContract> _
		Private Interface ISecureService
			<OperationContract> _
			Function Method1() As String
		End Interface

		Private Class SecureService
			Implements ISecureService
            <PrincipalPermission(SecurityAction.Demand, Role:="everyone")> _
            Public Function Method1() As String Implements ISecureService.Method1
                Return String.Format("Hello, ""{0}""", Thread.CurrentPrincipal.Identity.Name)
            End Function

		End Class

		Public Sub Run()
			Dim serviceUri As New Uri("http://localhost:8006/Service")
			Dim service As New ServiceHost(GetType(SecureService))
			service.AddServiceEndpoint(GetType(ISecureService), GetBinding(), serviceUri)
			service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles
			service.Open()

			Dim sr As New EndpointAddress(serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name))
			Dim cf As New ChannelFactory(Of ISecureService)(GetBinding(), sr)
			Dim client As ISecureService = cf.CreateChannel()
			Console.WriteLine("Client received response from Method1: {0}", client.Method1())
			CType(client, IChannel).Close()
			Console.ReadLine()
			service.Close()

		End Sub

		Public Shared Function GetBinding() As Binding
			Dim binding As New WSHttpBinding(SecurityMode.Message)
			binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
			Return binding
		End Function
	End Class
End Namespace

Приведенный ниже показано, как определить пользовательские.The following example shows how to specify Custom.

namespace CustomMode
{
    public class Test
    {
        public static void Main()
        {
            try
            {
                ShowPrincipalPermissionModeCustom ppwm = new ShowPrincipalPermissionModeCustom();
                ppwm.Run();

            }
            catch (Exception exc)
            {
                Console.WriteLine("Error: {0}", exc.Message);
                Console.ReadLine();
            }
        }
    }

    class ShowPrincipalPermissionModeCustom
    {
        [ServiceContract]
        interface ISecureService
        {
            [OperationContract]
            string Method1(string request);
        }

        [ServiceBehavior]
        class SecureService : ISecureService
        {
            [PrincipalPermission(SecurityAction.Demand, Role = "everyone")]
            public string Method1(string request)
            {
                return String.Format("Hello, \"{0}\"", Thread.CurrentPrincipal.Identity.Name);
            }
        }

        public void Run()
        {
            Uri serviceUri = new Uri(@"http://localhost:8006/Service");
            ServiceHost service = new ServiceHost(typeof(SecureService));
            service.AddServiceEndpoint(typeof(ISecureService), GetBinding(), serviceUri);
            List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>();
            policies.Add(new CustomAuthorizationPolicy());
            service.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly();
            service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;
            service.Open();

            EndpointAddress sr = new EndpointAddress(
                serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name));
            ChannelFactory<ISecureService> cf = new ChannelFactory<ISecureService>(GetBinding(), sr);
            ISecureService client = cf.CreateChannel();
            Console.WriteLine("Client received response from Method1: {0}", client.Method1("hello"));
            ((IChannel)client).Close();
            Console.ReadLine();
            service.Close();            
        }

        public static Binding GetBinding()
        {
            WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
            binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
            return binding;
        }

        class CustomAuthorizationPolicy : IAuthorizationPolicy
        {
            string id = Guid.NewGuid().ToString();

            public string Id
            {
                get { return this.id; }
            }

            public ClaimSet Issuer
            {
                get { return ClaimSet.System; }
            }

            public bool Evaluate(EvaluationContext context, ref object state)
            {
                object obj;
                if (!context.Properties.TryGetValue("Identities", out obj))
                    return false;

                IList<IIdentity> identities = obj as IList<IIdentity>;
                if (obj == null || identities.Count <= 0)
                    return false;

                context.Properties["Principal"] = new CustomPrincipal(identities[0]);
                return true;
            }
        }

        class CustomPrincipal : IPrincipal
        {
            IIdentity identity;
            public CustomPrincipal(IIdentity identity)
            {
                this.identity = identity;
            }

            public IIdentity Identity
            {
                get { return this.identity; }
            }

            public bool IsInRole(string role)
            {
                return true;
            }
        }
    }
}
Namespace CustomMode
	Public Class Test
		Public Shared Sub Main()
			Try
				Dim ppwm As New ShowPrincipalPermissionModeCustom()
				ppwm.Run()

			Catch exc As Exception
				Console.WriteLine("Error: {0}", exc.Message)
				Console.ReadLine()
			End Try
		End Sub
	End Class

	Friend Class ShowPrincipalPermissionModeCustom
		<ServiceContract> _
		Private Interface ISecureService
			<OperationContract> _
			Function Method1(ByVal request As String) As String
		End Interface

		<ServiceBehavior> _
		Private Class SecureService
			Implements ISecureService
            <PrincipalPermission(SecurityAction.Demand, Role:="everyone")> _
            Public Function Method1(ByVal request As String) As String Implements ISecureService.Method1
                Return String.Format("Hello, ""{0}""", Thread.CurrentPrincipal.Identity.Name)
            End Function
		End Class

		Public Sub Run()
			Dim serviceUri As New Uri("http://localhost:8006/Service")
			Dim service As New ServiceHost(GetType(SecureService))
			service.AddServiceEndpoint(GetType(ISecureService), GetBinding(), serviceUri)
			Dim policies As New List(Of IAuthorizationPolicy)()
			policies.Add(New CustomAuthorizationPolicy())
			service.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly()
			service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom
			service.Open()

			Dim sr As New EndpointAddress(serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name))
			Dim cf As New ChannelFactory(Of ISecureService)(GetBinding(), sr)
			Dim client As ISecureService = cf.CreateChannel()
			Console.WriteLine("Client received response from Method1: {0}", client.Method1("hello"))
			CType(client, IChannel).Close()
			Console.ReadLine()
			service.Close()
		End Sub

		Public Shared Function GetBinding() As Binding
			Dim binding As New WSHttpBinding(SecurityMode.Message)
			binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
			Return binding
		End Function

		Private Class CustomAuthorizationPolicy
			Implements IAuthorizationPolicy
			Private id_Renamed As String = Guid.NewGuid().ToString()

			Public ReadOnly Property Id() As String Implements System.IdentityModel.Policy.IAuthorizationComponent.Id
				Get
					Return Me.id_Renamed
				End Get
			End Property

			Public ReadOnly Property Issuer() As ClaimSet Implements IAuthorizationPolicy.Issuer
				Get
					Return ClaimSet.System
				End Get
			End Property

			Public Function Evaluate(ByVal context As EvaluationContext, ByRef state As Object) As Boolean Implements IAuthorizationPolicy.Evaluate
                Dim obj As Object = Nothing
				If (Not context.Properties.TryGetValue("Identities", obj)) Then
					Return False
				End If

				Dim identities As IList(Of IIdentity) = TryCast(obj, IList(Of IIdentity))
				If obj Is Nothing OrElse identities.Count <= 0 Then
					Return False
				End If

				context.Properties("Principal") = New CustomPrincipal(identities(0))
				Return True
			End Function
		End Class

		Private Class CustomPrincipal
			Implements IPrincipal
			Private identity_Renamed As IIdentity
			Public Sub New(ByVal identity As IIdentity)
				Me.identity_Renamed = identity
			End Sub

			Public ReadOnly Property Identity() As IIdentity Implements IPrincipal.Identity
				Get
					Return Me.identity_Renamed
				End Get
			End Property

			Public Function IsInRole(ByVal role As String) As Boolean Implements IPrincipal.IsInRole
				Return True
			End Function
		End Class
	End Class
End Namespace

Комментарии

При применении PrincipalPermissionAttribute к методу, с помощью этого режима можно указать, какой набор ролей следует использовать при авторизации доступа.When applying the PrincipalPermissionAttribute to a method, this mode specifies which set of roles to use when authorizing access. По умолчанию атрибут использует группы Windows (например, Administrator или Users) для указания роли, к которой должен принадлежать пользователь.By default, the attribute uses Windows groups (such as Administrator or Users) to specify the role to which the user must belong.

Чтобы задать режим программно, необходимо создать экземпляр класса ServiceHost, найти ServiceAuthorizationBehavior в его коллекции расширений функциональности и задать PrincipalPermissionMode для соответствующего перечисления.To set the mode programmatically, create an instance of the ServiceHost class, then find the ServiceAuthorizationBehavior in its collection of behaviors, and set the PrincipalPermissionMode to the appropriate enumeration. Следующий пример задает свойство для UseAspNetRoles.The following example sets the property to UseAspNetRoles.

ServiceHost myServiceHost = new ServiceHost(typeof(Calculator), baseUri);
ServiceAuthorizationBehavior myServiceBehavior =
    myServiceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
myServiceBehavior.PrincipalPermissionMode =
    PrincipalPermissionMode.UseAspNetRoles;
Dim myServiceHost As New ServiceHost(GetType(Calculator), baseUri)
Dim myServiceBehavior As ServiceAuthorizationBehavior = myServiceHost.Description.Behaviors.Find(Of ServiceAuthorizationBehavior)()
myServiceBehavior.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles

Кроме того, можно задать в конфигурации поведение, добавив <serviceAuthorization> для <serviceBehaviors> из файл конфигурации, как показано в следующем коде.You can also set the behavior in configuration by adding a <serviceAuthorization> to the <serviceBehaviors> of a configuration file, as shown in the following code.

// Only a client authenticated with a valid certificate that has the 
// specified subject name and thumbprint can call this method.
[PrincipalPermission(SecurityAction.Demand,
     Name = "CN=ReplaceWithSubjectName; 123456712345677E8E230FDE624F841B1CE9D41E")]
public double Multiply(double a, double b)
{
    return a * b;
}
' Only a client authenticated with a valid certificate that has the 
' specified subject name and thumbprint can call this method.
<PrincipalPermission(SecurityAction.Demand, Name := "CN=ReplaceWithSubjectName; 123456712345677E8E230FDE624F841B1CE9D41E")> _
Public Function Multiply(ByVal a As Double, ByVal b As Double) As Double
	Return a * b
End Function

Перечисление влияет на способ авторизации пользователя атрибутом PrincipalPermissionAttribute при применении этого атрибута к методу.The enumeration affects how the PrincipalPermissionAttribute attribute authorizes a user when it is applied to a method. В следующем примере показано, как применить атрибут к методу. Для этого необходимо, чтобы пользователь принадлежал к группе «Пользователи» на компьютере.The following example applies the attribute to a method and demands that the user belong to the Users group on the computer. Данный код работает только в том случае, если PrincipalPermissionMode имеет значение UseWindowsGroup (по умолчанию).This code works only when the PrincipalPermissionMode is set to UseWindowsGroup (the default setting).

// Only members of the CalculatorClients group can call this method.
[PrincipalPermission(SecurityAction.Demand, Role = "Users")]
public double Add(double a, double b)
{
    return a + b;
}
' Only members of the CalculatorClients group can call this method.
<PrincipalPermission(SecurityAction.Demand, Role := "Users")> _
Public Function Add(ByVal a As Double, ByVal b As Double) As Double
	Return a + b
End Function

UseAspNetRolesUseAspNetRoles

Значение UseAspNetRoles используется для всех типов учетных данных.The UseAspNetRoles value is used for all credential types. Этот режим позволяет Windows Communication Foundation (WCF) использовать поставщика ролей ASP.NET для принятия решений об авторизации.This mode enables Windows Communication Foundation (WCF) to use the ASP.NET role provider to make authorization decisions.

Если для службы в качестве учетных данных используется сертификат X.509, можно присвоить свойству Name для PrincipalPermissionAttribute строковое значение, которое включает составные значение полей «Тема» и «Отпечаток пальца», как показано в следующем примере кода.When the credential for a service is an X.509 certificate, you can set the Name property of the PrincipalPermissionAttribute to a string that consists of the concatenated values of the Subject field and the Thumbprint field, as shown in the following example.

ServiceHost myServiceHost = new ServiceHost(typeof(Calculator), baseUri);
ServiceAuthorizationBehavior myServiceBehavior =
    myServiceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
myServiceBehavior.PrincipalPermissionMode =
    PrincipalPermissionMode.UseAspNetRoles;
MyServiceAuthorizationManager sm = new MyServiceAuthorizationManager();
myServiceBehavior.ServiceAuthorizationManager = sm;
Dim myServiceHost As New ServiceHost(GetType(Calculator), baseUri)
Dim myServiceBehavior As ServiceAuthorizationBehavior = myServiceHost.Description.Behaviors.Find(Of ServiceAuthorizationBehavior)()
myServiceBehavior.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles
Dim sm As New MyServiceAuthorizationManager()
myServiceBehavior.ServiceAuthorizationManager = sm

Составное строковое значение состоит из значений темы и отпечатка пальца, разделенных точкой с запятой и пробелом.The concatenated string consists of the subject and thumbprint values separated by a semicolon and a space.

Возможно также использовать пустую строку в поле «Тема» в сертификате.It is also possible for a certificate to have a Subject field set to a null string. В этом случае можно задать свойство Name как точку с запятой, за которой следует пробел, а затем значение отпечатка пальца, как показано в следующем примере кода.In that case, you can set the Name property to a semicolon followed by a space and then the thumbprint, as shown in the following example.

// Only a client authenticated with a valid certificate that has the 
// specified thumbprint can call this method.
[PrincipalPermission(SecurityAction.Demand,
     Name = "; 123456712345677E8E230FDE624F841B1CE9D41E")]
public double Divide(double a, double b)
{
    return a * b;
}
' Only a client authenticated with a valid certificate that has the 
' specified thumbprint can call this method.
<PrincipalPermission(SecurityAction.Demand, Name := "; 123456712345677E8E230FDE624F841B1CE9D41E")> _
Public Function Divide(ByVal a As Double, ByVal b As Double) As Double
	Return a * b
End Function

Если используется поставщик ролей ASP.NET, можно также назначить для свойства Role роль в базе данных.If an ASP.NET role provider is present, you can also set the Role property to a role in the database. По умолчанию база данных представлена SqlRoleProvider.By default, the database is represented by the SqlRoleProvider. Также можно задать настраиваемый поставщик ролей с помощью свойства RoleProvider класса ServiceAuthorizationBehavior.You can also set a custom role provider with the RoleProvider property of the ServiceAuthorizationBehavior class. В следующем примере кода показано, как присвоить роли значение Administrators.The following code sets the role to Administrators. Следует учесть, что поставщик ролей должен сопоставлять учетную запись пользователя с данной ролью.Note that the role provider must map the user account to that role.

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
public string ReadFile(string fileName)
{
    // Code not shown.
    return "Not implemented";
}
<PrincipalPermission(SecurityAction.Demand, Role := "Administrators")> _
Public Function ReadFile(ByVal fileName As String) As String
	' Code not shown.
	Return "Not implemented"
End Function

Дополнительные сведения о поставщике ролей ASP.NET см. в разделе How To: использование диспетчера ролей в ASP.NET 2.0.For more information about the ASP.NET Role provider, see How To: Use Role Manager in ASP.NET 2.0.

Дополнительные сведения об использовании WCF и поставщика ролей см. в разделе как: использование поставщика ролей ASP.NET со службой.For more information about using WCF and the role provider, see How to: Use the ASP.NET Role Provider with a Service.

ДругойCustom

Если свойство имеет значение значение Custom, необходимо также указать пользовательский класс, реализующий IAuthorizationPolicy класса.When the property is set to Custom, you must also provide a custom class that implements the IAuthorizationPolicy class. Этот класс обеспечивает представление вызывающего оператора IPrincipal в коллекции Properties.This class is responsible for providing the caller's IPrincipal representation inside the Properties collection. Экземпляр IPrincipal должен сохраняться в коллекции свойств с помощью строкового ключа «Главный», как показано в следующем примере.It must store the IPrincipal instance to the properties collection using the "Principal" string key, as shown in the following example.

evaluationContext.Properties["Principal"]=new CustomPrincipal(identity);  

ФонBackground

Безопасность на основе ролей в .NET Framework.NET Framework разрешает приложениям задавать авторизацию посредством кода.The role-based security in .NET Framework.NET Framework enables applications to specify authorizations through code. Если задано требование PrincipalPermission, CurrentPrincipal должен соответствовать требованиям PrincipalPermission.By specifying the PrincipalPermission demand, the CurrentPrincipal must satisfy the PrincipalPermission requirement. Например, пользователь должен принадлежать к определенной роли или группе.For example, that the user must be in a specific role or group. В противном случае поток не будет авторизован для выполнения кода и возникнет исключение.Otherwise, the thread is not authorized to execute the code, which results in an exception. WCF предоставляет набор PrincipalPermissionMode выбранные параметры для указания CurrentPrincipal на основе SecurityContext соответствующим образом.WCF provides a set of PrincipalPermissionMode selections to specify the CurrentPrincipal based on SecurityContext accordingly.

Применяется к