如何在每个请求中将winform自定义用户凭据传递给WCF服务?

问题描述 投票:0回答:1

我想要实现的是在每个请求中将凭证/令牌传递给WCF服务。顺便说一句,这个凭证不是Windows凭证,它们是从自定义数据库中提取的,而且身份验证逻辑非常简单,tenantId +用户名+密码。

我目前正在使用消息检查器在标头中插入这些信息,并从服务器端检查器中获取它们(使用OperationContext)。

但为了保持线程安全,我必须在每个winform请求中包装请求,如下所示:

using (new OperationContextScope((WcfService as ServiceClient).InnerChannel))
{
   MessageHeader hdXXId = MessageHeader.CreateHeader("XXId", "CustomHeader", WinformSomeVariable.XXId);
   OperationContext.Current.OutgoingMessageHeaders.Add(hdXXId);

   _objXX = WcfService.GetXXById(id);

}

如上所示,这很重,显然不是处理这种情况的聪明方法。那么有没有办法安全地保存这些信息,并且可以在WCF检查员中获取它们?

非常感谢!

PS。感谢@Abraham Qian,我一直很傻。只需将客户端检查器置于同一个winform项目中即可解决此问题。

c# winforms wcf
1个回答
0
投票

只需忽略如何重构身份验证的问题。至于如何使用IClientMessageInspector接口创建持久性消息头,以下代码片段可能很有用(假设使用Channel Factory调用)

class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:1300");
            IService service = ChannelFactory<IService>.CreateChannel(new BasicHttpBinding(), new EndpointAddress(uri));
            try
            {
                Console.WriteLine(service.SayHello());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }

    [ServiceContract(Namespace = "mydomain")]
    [CustomContractBehavior]
    public interface IService
    {
        [OperationContract]
        string SayHello();
    }

    public class ClientMessageLogger : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            string displayText = $"the client has received the reply:\n{reply}\n";
            Console.Write(displayText);
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
        //Add custom message header
            request.Headers.Add(MessageHeader.CreateHeader("myheader","mynamespace",2000));
            string displayText = $"the client send request message:\n{request}\n";
            Console.WriteLine(displayText);
            return null;

        }
    }

    public class CustomContractBehaviorAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
    {
        public Type TargetContract => typeof(IService);

        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            return;
        }

        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new ClientMessageLogger());
        }

        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
            return;
        }

        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
            return;
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.