PrincipalPermissionMode Enum

Definitie

Hiermee stelt u de modus voor autorisatiecontroles in wanneer u de PrincipalPermissionAttribute toegang tot een methode wilt beheren.

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

Velden

Name Waarde Description
None 0

CurrentPrincipal is niet ingesteld.

UseWindowsGroups 1

CurrentPrincipal is ingesteld op basis van Windows (WindowsPrincipal). Als de gebruikersidentiteit niet is gekoppeld aan een Windows-account, wordt anonieme Windows gebruikt.

UseAspNetRoles 2

CurrentPrincipal is ingesteld op basis van de ASP.NET rolprovider (RoleProvider).

Custom 3

Hiermee kan de gebruiker een aangepaste IPrincipal klasse opgeven voor CurrentPrincipal.

Always 4

Hiermee kan de gebruiker altijd een IPrincipal klasse opgeven voor CurrentPrincipal.

Voorbeelden

In het volgende voorbeeld ziet u hoe u UseAspNetRoles opgeeft.

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

In het volgende voorbeeld ziet u hoe u Aangepast opgeeft.

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

Opmerkingen

Wanneer u de PrincipalPermissionAttribute methode toepast op een methode, geeft deze modus aan welke set rollen moet worden gebruikt bij het autoriseren van toegang. Standaard gebruikt het kenmerk Windows groepen (zoals Administrator of Users) om de rol op te geven waartoe de gebruiker moet behoren.

Als u de modus programmatisch wilt instellen, maakt u een exemplaar van de ServiceHost klasse, zoekt u de ServiceAuthorizationBehavior in de verzameling gedragingen en stelt u de PrincipalPermissionMode op de juiste opsomming in. In het volgende voorbeeld wordt de eigenschap ingesteld op 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

U kunt het gedrag in de configuratie ook instellen door een <serviceAuthorization> toe te voegen aan de <serviceBehaviors> van een configuratiebestand, zoals wordt weergegeven in de volgende 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

De opsomming beïnvloedt hoe het PrincipalPermissionAttribute kenmerk een gebruiker autoriseert wanneer deze wordt toegepast op een methode. In het volgende voorbeeld wordt het kenmerk toegepast op een methode en wordt vereist dat de gebruiker deel uitmaakt van de groep Gebruikers op de computer. Deze code werkt alleen wanneer de PrincipalPermissionMode code is ingesteld op UseWindowsGroup (de standaardinstelling).

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

De waarde UseAspNetRoles wordt gebruikt voor alle referentietypen. Met deze modus kan Windows Communication Foundation (WCF) de ASP.NET rolprovider gebruiken om autorisatiebeslissingen te nemen.

Wanneer de referentie voor een service een X.509-certificaat is, kunt u de Name eigenschap van de PrincipalPermissionAttribute eigenschap instellen op een tekenreeks die bestaat uit de samengevoegde waarden van het veld Onderwerp en het veld Vingerafdruk, zoals wordt weergegeven in het volgende voorbeeld.

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

De samengevoegde tekenreeks bestaat uit de onderwerp- en vingerafdrukwaarden, gescheiden door een puntkomma en een spatie.

Het is ook mogelijk dat een certificaat een onderwerpveld heeft ingesteld op een null-tekenreeks. In dat geval kunt u de Name eigenschap instellen op een puntkomma, gevolgd door een spatie en vervolgens de vingerafdruk, zoals wordt weergegeven in het volgende voorbeeld.

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

Als er een ASP.NET rolprovider aanwezig is, kunt u ook de eigenschap Role instellen op een rol in de database. De database wordt standaard vertegenwoordigd door de SqlRoleProvider. U kunt ook een aangepaste rolprovider instellen met de RoleProvider eigenschap van de ServiceAuthorizationBehavior klasse. Met de volgende code wordt de rol ingesteld op Administrators. Houd er rekening mee dat de rolprovider het gebruikersaccount moet toewijzen aan die 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

Zie How to: Use the ASP.NET Role Provider with a Service voor meer informatie over het gebruik van WCF en de rolprovider.

Op maat gemaakt

Wanneer de eigenschap is ingesteld op Aangepast, moet u ook een aangepaste klasse opgeven waarmee de IAuthorizationPolicy klasse wordt geïmplementeerd. Deze klasse is verantwoordelijk voor het leveren van de weergave van IPrincipal de beller in de Properties verzameling. Het moet het IPrincipal exemplaar opslaan in de eigenschappenverzameling met behulp van de tekenreekssleutel Principal, zoals wordt weergegeven in het volgende voorbeeld.

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

Achtergrond

Met de beveiliging op basis van rollen in .NET Framework kunnen toepassingen autorisaties opgeven via code. Door de PrincipalPermission vraag op te geven, moet de CurrentPrincipal vraag voldoen aan de PrincipalPermission vereiste. Bijvoorbeeld dat de gebruiker zich in een specifieke rol of groep moet bevinden. Anders is de thread niet gemachtigd om de code uit te voeren, wat resulteert in een uitzondering. WCF biedt een set PrincipalPermissionMode selecties om de CurrentPrincipal op basis daarvan op SecurityContext te geven.

Van toepassing op