次の方法で共有


方法: カスタム プリンシパル ID を作成する

PrincipalPermissionAttributeは、サービス メソッドへのアクセスを制御する宣言型の手段です。 この属性を使用する場合、 PrincipalPermissionMode 列挙体は、承認チェックを実行するためのモードを指定します。 このモードを Custom に設定すると、ユーザーは CurrentPrincipal プロパティによって返されるカスタム IPrincipal クラスを指定できます。 このトピックでは、 Custom をカスタム承認ポリシーとカスタム プリンシパルと組み合わせて使用するシナリオについて説明します。

PrincipalPermissionAttributeの使用方法の詳細については、「方法: PrincipalPermissionAttribute クラスを使用してアクセスを制限する」を参照してください。

namespace CustomMode
{
    public class Test
    {
        public static void Main()
        {
            try
            {
                ShowPrincipalPermissionModeCustom ppwm = new ShowPrincipalPermissionModeCustom();
                ppwm.Run();
            }
            catch (Exception exc)
            {
                Console.WriteLine($"Error: {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: {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

コードのコンパイル

コードをコンパイルするには、次の名前空間への参照が必要です。

こちらもご覧ください