PrincipalPermissionMode Wyliczenie

Definicja

Ustawia tryb sprawdzania autoryzacji podczas używania metody PrincipalPermissionAttribute do kontrolowania dostępu do metody.

public enum class PrincipalPermissionMode
public enum PrincipalPermissionMode
type PrincipalPermissionMode = 
Public Enum PrincipalPermissionMode
Dziedziczenie
PrincipalPermissionMode

Pola

Always 4

Zawsze umożliwia użytkownikowi określenie IPrincipal klasy dla CurrentPrincipalklasy .

Custom 3

Umożliwia użytkownikowi określenie niestandardowej IPrincipal klasy dla CurrentPrincipalelementu .

None 0

CurrentPrincipal nie jest ustawiona.

UseAspNetRoles 2

CurrentPrincipal jest ustawiana na podstawie dostawcy ról ASP.NET (RoleProvider).

UseWindowsGroups 1

CurrentPrincipal jest ustawiana na podstawie systemu Windows (WindowsPrincipal). Jeśli tożsamość użytkownika nie jest skojarzona z kontem systemu Windows, jest używany anonimowy system Windows.

Przykłady

W poniższym przykładzie pokazano, jak określić element 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

W poniższym przykładzie pokazano, jak określić wartość niestandardową.

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

Uwagi

Podczas stosowania PrincipalPermissionAttribute metody do metody ten tryb określa zestaw ról do użycia podczas autoryzowania dostępu. Domyślnie atrybut używa grup systemu Windows (takich jak Administrator lub Users) do określenia roli, do której musi należeć użytkownik.

Aby ustawić tryb programowo, utwórz wystąpienie ServiceHost klasy, a następnie znajdź ServiceAuthorizationBehavior element w swojej kolekcji zachowań i ustaw PrincipalPermissionMode wartość na odpowiednią wyliczenie. W poniższym przykładzie właściwość jest ustawiana na 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

Zachowanie można również ustawić w konfiguracji, dodając <element serviceAuthorization> do<elementu serviceBehaviors> pliku konfiguracji, jak pokazano w poniższym kodzie.

// 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

Wyliczenie ma wpływ na to, jak PrincipalPermissionAttribute atrybut autoryzuje użytkownika podczas stosowania go do metody. Poniższy przykład stosuje atrybut do metody i wymaga, aby użytkownik należał do grupy Użytkownicy na komputerze. Ten kod działa tylko wtedy, gdy PrincipalPermissionMode parametr jest ustawiony na UseWindowsGroup (ustawienie domyślne).

// 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

UseAspNetRoles

Wartość UseAspNetRoles jest używana dla wszystkich typów poświadczeń. Ten tryb umożliwia programowi Windows Communication Foundation (WCF) używanie dostawcy roli ASP.NET do podejmowania decyzji dotyczących autoryzacji.

Gdy poświadczenie usługi jest certyfikatem X.509, można ustawić Name właściwość PrincipalPermissionAttribute ciągu składającego się z połączonych wartości pola Temat i pola Odcisk palca, jak pokazano w poniższym przykładzie.

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

Połączony ciąg składa się z wartości tematu i odcisku palca oddzielonych średnikami i spacją.

Istnieje również możliwość, aby certyfikat miał pole Podmiot ustawione na ciąg o wartości null. W takim przypadku można ustawić Name właściwość na średnik, a następnie spację, a następnie odcisk palca, jak pokazano w poniższym przykładzie.

// 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

Jeśli istnieje dostawca roli ASP.NET, możesz również ustawić Role właściwość na rolę w bazie danych. Domyślnie baza danych jest reprezentowana przez SqlRoleProviderelement . Można również ustawić niestandardowego dostawcę roli z RoleProvider właściwością ServiceAuthorizationBehavior klasy. Poniższy kod ustawia rolę na Administrators. Należy pamiętać, że dostawca roli musi zamapować konto użytkownika na rolę.

[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

Aby uzyskać więcej informacji na temat korzystania z programu WCF i dostawcy ról, zobacz Instrukcje: używanie dostawcy ról ASP.NET z usługą.

Niestandardowy

Gdy właściwość jest ustawiona na Wartość Niestandardowa, należy również podać klasę niestandardową, która implementuje klasę IAuthorizationPolicy . Ta klasa jest odpowiedzialna za zapewnienie reprezentacji obiektu wywołującego IPrincipal w kolekcji Properties . Wystąpienie musi być przechowywane w IPrincipal kolekcji właściwości przy użyciu klucza ciągu "Principal", jak pokazano w poniższym przykładzie.

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

Tło

Zabezpieczenia oparte na rolach w .NET Framework umożliwiają aplikacjom określanie autoryzacji za pomocą kodu. PrincipalPermission Określając zapotrzebowanie, CurrentPrincipal musi spełniać PrincipalPermission wymagania. Na przykład użytkownik musi należeć do określonej roli lub grupy. W przeciwnym razie wątek nie jest autoryzowany do wykonywania kodu, co powoduje wyjątek. Program WCF udostępnia zestaw wyborów PrincipalPermissionMode do określenia CurrentPrincipal odpowiednio na SecurityContext podstawie.

Dotyczy