다음을 통해 공유


PrincipalPermissionMode 열거형

정의

PrincipalPermissionAttribute를 사용하여 메서드에 대한 액세스를 제어할 때 권한 부여 확인 모드를 설정합니다.

public enum class PrincipalPermissionMode
public enum PrincipalPermissionMode
type PrincipalPermissionMode = 
Public Enum PrincipalPermissionMode
상속
PrincipalPermissionMode

필드

Always 4

항상 사용자가 IPrincipal에 대한 사용자 지정 CurrentPrincipal 클래스를 지정할 수 있도록 합니다.

Custom 3

사용자가 IPrincipal에 대한 사용자 지정 CurrentPrincipal 클래스를 지정할 수 있도록 합니다.

None 0

CurrentPrincipal은 설정되지 않습니다.

UseAspNetRoles 2

CurrentPrincipal 는 ASP.NET 역할 공급자(RoleProvider)에 따라 설정됩니다.

UseWindowsGroups 1

CurrentPrincipal은 Windows(WindowsPrincipal)를 기반으로 설정됩니다. 사용자 ID가 Windows 계정에 연결되어 있지 않으면 익명의 Windows 계정이 사용됩니다.

예제

다음 예제에서는 하도록 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

다음 예제에서는 사용자 지정을 지정 하는 방법을 보여 줍니다.

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를 메서드에 적용할 경우 이 모드는 액세스 권한을 부여할 때 사용할 역할을 지정합니다. 기본적으로 이 특성은 Windows 그룹(예: Administrator 또는 Users)을 사용하여 사용자가 속해야 할 역할을 지정합니다.

모드를 프로그래밍 방식으로 설정하려면 ServiceHost 클래스의 인스턴스를 만들고 동작 컬렉션에서 ServiceAuthorizationBehavior를 찾은 다음 PrincipalPermissionMode를 해당 열거형으로 설정합니다. 다음 예제에서는 하도록 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

다음 코드와 같이 구성 파일의 serviceBehaviors>에 serviceAuthorization<>을 추가하여< 구성에서 동작을 설정할 수도 있습니다.

// 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 특성이 메서드에 적용될 때 사용자의 권한을 부여하는 방법에 영향을 줍니다. 다음 예제에서는 메서드에 특성을 적용하고 사용자가 컴퓨터의 사용자 그룹에 속하도록 요청합니다. 이 코드는 PrincipalPermissionModeUseWindowsGroup으로 설정되어 있는 경우에만 실행됩니다.

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

하도록 UseAspNetRoles 값은 모든 자격 증명 형식에 사용 됩니다. Windows Communication Foundation (WCF)를 ASP.NET 역할 공급자를 사용 하 여 권한 부여 결정을 내릴 수 있습니다.

서비스에 대한 자격 증명이 X.509 인증서인 경우 다음 예제에서처럼 NamePrincipalPermissionAttribute 속성을 Subject(주체) 필드 값과 Thumbprint(지문) 필드 값을 연결하여 구성된 문자열로 설정할 수 있습니다.

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

연결된 문자열은 주체 값과 지문 값이 세미콜론과 공백으로 구분되어 구성됩니다.

인증서에서 Subject 필드를 null 문자열로 설정할 수도 있습니다. 그럴 경우 아래 예제에서처럼 세미콜론, 공백, 지문을 차례로 입력하여 Name 속성을 설정할 수 있습니다.

// 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 속성을 데이터베이스에 있는 역할로 설정할 수도 있습니다. 기본적으로 데이터베이스는 SqlRoleProvider로 표시됩니다. RoleProvider 속성이 ServiceAuthorizationBehavior 클래스인 사용자 지정 역할 공급자를 설정할 수도 있습니다. 다음 코드에서는 역할을 Administrators로 설정합니다. 역할 공급자는 사용자 계정을 해당 역할에 매핑해야 합니다.

[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

WCF 및 역할 공급자 사용에 대 한 자세한 내용은 참조 하세요. 방법: ASP.NET 역할 공급자를 사용 하 여 서비스를 사용 하 여입니다.

사용자 지정

사용자 지정 속성을 설정도 구현 하는 사용자 지정 클래스를 제공 해야 합니다는 IAuthorizationPolicy 클래스입니다. 이 클래스는 IPrincipal 컬렉션 내에서 호출자의 Properties을 표시하는 기능을 제공합니다. 다음 예제에서처럼 "Principal" 문자열 키를 사용하여 속성 컬렉션에 IPrincipal 인스턴스를 저장해야 합니다.

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

배경

.NET Framework 역할 기반 보안을 사용하면 애플리케이션이 코드를 통해 권한 부여를 지정할 수 있습니다. PrincipalPermissionCurrentPrincipal 요청을 지정하여 PrincipalPermission 요구 사항을 충족시켜야 합니다. 예를 들어, 사용자가 특정 역할이나 그룹에 속해야 할 수 있습니다. 그렇지 않으면 스레드가 코드를 실행할 권한이 없으므로 예외가 발생합니다. WCF의 집합을 제공 PrincipalPermissionMode 지정 하려면 선택 합니다 CurrentPrincipal 기반으로 SecurityContext 적절 하 게 합니다.

적용 대상