在肥皂请求的标头中发送用户名令牌的最佳方法是什么?

发布于 2025-01-18 00:32:29 字数 4598 浏览 4 评论 0原文

    public async Task GetUserInfoAsync(){
        TestClient client = new TestClient();

        client.Endpoint.EndpointBehaviors.Add(new WsSecurityEndpointBehavior("test", "12345"));

        client.GetUserInfo(new GetUserInfoRequest{
                token = "866-563-6746"
        })
    }


    public class WsSecurityEndpointBehavior : IEndpointBehavior
    {
        private readonly string _username;
        private readonly string _password;

        public WsSecurityEndpointBehavior(string username, string password)
        {
            _username = username;
            _password = password;
        }

        public void AddBindingParameters(ServiceEndpoint endpoint,
                BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new WsSecurityMessageInspector(_username, _password));
        }
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }

    public class WsSecurityMessageInspector : IClientMessageInspector
    {
        private readonly string _username;
        private readonly string _password;

        public WsSecurityMessageInspector(string username, string password)
        {
            _username = username;
            _password = password;
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            var header = new Security
            {
                UsernameToken =
                    {
                        Password = new Password
                        {
                            Value = _password,
                            Type =
                                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
                        },
                        Username = _username
                    }
            };

            request.Headers.Add(header);

            return null;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
        }
    }

    public class Password
    {
        [XmlAttribute] public string Type { get; set; }

        [XmlText] public string Value { get; set; }
    }

    [XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
    public class UsernameToken
    {
        [XmlElement] public string Username { get; set; }

        [XmlElement] public Password Password { get; set; }
    }

    public class Security : MessageHeader
    {
        public Security()
        {
            UsernameToken = new UsernameToken();
        }

        public UsernameToken UsernameToken { get; set; }

        public override string Name => GetType().Name;

        public override string Namespace =>
            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

        public override bool MustUnderstand => true;

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            var serializer = new XmlSerializer(typeof(UsernameToken));
            serializer.Serialize(writer, UsernameToken);
        }
    }

我在上述结构中成功地将UserNametoken添加到标题中,并在GetUserInfoAsync中发送的用户名和密码参数。使用此结构,我可以获得以下XML输出。

但是我也认为有比这更好的方法。在这里,我想设置一个可以在每个肥皂请求中使用的动态结构。最好的方法是什么?

<soapenv:Envelope xmlns:pos="http://test.test.com/xmlschema/pos" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurityutility-1.0.xsd">
        <wsse:UsernameToken>
            <wsse:Username>test</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile1.0#PasswordText">12345</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>
<soapenv:Body>
    <pos:GetUserInfoRequest>
        <pos:token>866-563-6746</pos:token>
    </pos:GetUserInfoRequest>
</soapenv:Body></soapenv:Envelope>
    public async Task GetUserInfoAsync(){
        TestClient client = new TestClient();

        client.Endpoint.EndpointBehaviors.Add(new WsSecurityEndpointBehavior("test", "12345"));

        client.GetUserInfo(new GetUserInfoRequest{
                token = "866-563-6746"
        })
    }


    public class WsSecurityEndpointBehavior : IEndpointBehavior
    {
        private readonly string _username;
        private readonly string _password;

        public WsSecurityEndpointBehavior(string username, string password)
        {
            _username = username;
            _password = password;
        }

        public void AddBindingParameters(ServiceEndpoint endpoint,
                BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new WsSecurityMessageInspector(_username, _password));
        }
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }

    public class WsSecurityMessageInspector : IClientMessageInspector
    {
        private readonly string _username;
        private readonly string _password;

        public WsSecurityMessageInspector(string username, string password)
        {
            _username = username;
            _password = password;
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            var header = new Security
            {
                UsernameToken =
                    {
                        Password = new Password
                        {
                            Value = _password,
                            Type =
                                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
                        },
                        Username = _username
                    }
            };

            request.Headers.Add(header);

            return null;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
        }
    }

    public class Password
    {
        [XmlAttribute] public string Type { get; set; }

        [XmlText] public string Value { get; set; }
    }

    [XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
    public class UsernameToken
    {
        [XmlElement] public string Username { get; set; }

        [XmlElement] public Password Password { get; set; }
    }

    public class Security : MessageHeader
    {
        public Security()
        {
            UsernameToken = new UsernameToken();
        }

        public UsernameToken UsernameToken { get; set; }

        public override string Name => GetType().Name;

        public override string Namespace =>
            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

        public override bool MustUnderstand => true;

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            var serializer = new XmlSerializer(typeof(UsernameToken));
            serializer.Serialize(writer, UsernameToken);
        }
    }

I successfully add UsernameToken to the header with the username and password parameters I sent in GetUserInfoAsync in the above structure. With this structure, I can get the following xml output.

But I also think there is a better way than this. Here I want to set up a dynamic structure that I can use in every soap request. What is the best way to do this?

<soapenv:Envelope xmlns:pos="http://test.test.com/xmlschema/pos" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurityutility-1.0.xsd">
        <wsse:UsernameToken>
            <wsse:Username>test</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile1.0#PasswordText">12345</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>
<soapenv:Body>
    <pos:GetUserInfoRequest>
        <pos:token>866-563-6746</pos:token>
    </pos:GetUserInfoRequest>
</soapenv:Body></soapenv:Envelope>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文