【问题标题】:How to get a token from a WCF service如何从 WCF 服务获取令牌
【发布时间】:2014-10-08 11:17:58
【问题描述】:

我的组织托管了一个 WCF 服务,外部用户可以向我们发送数据。我们有几个发件人可以正常运行,但我正在帮助一个遇到问题的发件人。发件人未使用 Microsoft 技术,因此我正在协助他们构建将连接到我们服务的 XML 数据包。

目前我正在尝试构建 XML 以在我的服务上调用 RequestSecurityToken。这是我发送的 XML 示例,其中删除了安全细节:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
   xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:us="our namespace url"
   xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
   xmlns:addr="http://www.w3.org/2005/08/addressing"
   xmlns:wsu="http://doc.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <SOAP-ENV:Header>
        <addr:Action SOAP-ENV:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</addr:Action>
        <addr:MessageID>urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</addr:MessageID>
        <addr:ReplyTo>
            <addr:Address>http://www.w3.org/2005/08/addressing/anonymous</addr:Address>
        </addr:ReplyTo>
        <addr:To SOAP-ENV:mustUnderstand="1">https://our.domain/path/ServiceName.svc</addr:To>
        <wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsu:Timestamp wsu:Id="uuid-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-x">
                <wsu:Created>2014-08-14T10:07:00.095Z</wsu:Created>
                <wsu:Expires>2014-08-14T10:09:05.095Z</wsu:Expires>
            </wsu:Timestamp>
            <wsse:UsernameToken wsu:Id="uuid-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-x">
                <wsse:Username>TST</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wsse/2004/01/oasis-200401-wsse-username-token-profile-1.0#PasswordText">Test</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <trust:RequestSecurityToken xmlns:trust="http://schemas.xmlsoap.org/ws/2005/02/trust">
            <trust:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</trust:TokenType>
            <trust:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</trust:RequestType>
            <trust:Entropy>
                <trust:BinarySecret wsu:Id="uuid-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-x" Type="http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=</trust:BinarySecret>
            </trust:Entropy>
            <trust:KeySize>256</trust:KeySize>
        </trust:RequestSecurityToken>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

这是回复:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
        <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
        <a:RelatesTo>urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</a:RelatesTo>
    </s:Header>
    <s:Body>
        <s:Fault>
            <s:Code>
                <s:Value>s:Sender</s:Value>
                <s:Subcode>
                    <s:Value xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</s:Value>
                </s:Subcode>
            </s:Code>
            <s:Reason>
                <s:Text xml:lang="en-US">An error occurred when verifying security for the message.</s:Text>
            </s:Reason>
        </s:Fault>
    </s:Body>
</s:Envelope>

【问题讨论】:

  • 哇,看起来很难用 SOAP 解决。您可能会检查客户端是否在标头中发送内容长度。我知道这不是您要寻找的答案,但想知道使用 REST 是否更容易。我在跨平台 Web 服务中使用 REST 的运气更好。
  • 是的,内容长度是在发送上述内容的测试应用程序中发送的。不幸的是,这个系统已经建成并投入生产。不太可能将其重建为 REST 服务。
  • @WilliamWalseth。我们将使用 Web API 将其重建为 REST 服务。如果您将发布与您的评论类似的内容作为答案,我将很乐意接受。

标签: xml wcf wcf-security ws-security


【解决方案1】:

这是一个简单的 C# REST(ish) 服务器,它在 HTTP Post 中接受 XML。
您还可以将其修改为使用 HTTP 获取参数、在标头中隐藏您的安全凭证、使用基本身份验证等。

希望你觉得这很有用。

namespace webservice {
    public partial class datasvc : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            XmlDocument xmlResponse = new XmlDocument();
            xmlResponse.LoadXml("<xml/>");



            try {
                XmlDocument xmlRequest = new XmlDocument();
                xmlRequest.Load(Request.InputStream);

                if (xmlRequest.DocumentElement.HasAttribute("id") &&
                    xmlRequest.DocumentElement.HasAttribute("pw")) {
                    // OK verify
                } else {
                    throw new Exception("Invalid credentials");
                }


                switch (xmlRequest.DocumentElement.GetAttribute("service")) {
                    case "time":
                        xmlResponse.DocumentElement.SetAttribute("content", DateTime.Now.ToString());
                        break;

                    case "hello":
                        xmlResponse.DocumentElement.SetAttribute("content", "Hello World");
                        break;

                    default:
                        throw new Exception("Unknown Service");
                }


            } catch (Exception ex) {
                xmlResponse.DocumentElement.SetAttribute("err", ex.Message);
            } finally {
                Response.ContentType = "text/xml";
                Response.Write(xmlResponse.OuterXml);
            }
        }
    }
}

从 .NET 调用它是一个客户端

namespace webservice {
    public partial class client : System.Web.UI.Page {

        /// <summary>Posts the specified document to the server using UTF-8 encoding.</summary>             
        public XmlDocument postXml(XmlDocument xml, String strURL, string strID, string strPassword) {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strURL);
            req.Method = "POST";
            req.ContentType = "text/xml";
            XmlDocument xmlReturn = new XmlDocument();
            req.Timeout = 180000;


            // UGH! not set by default!
            req.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

            // Write the serialized XML to the request
            Stream rs = req.GetRequestStream();

            XmlTextWriter tw = new XmlTextWriter(rs, Encoding.UTF8); // Encoding.GetEncoding("UTF-8"));
            xml.WriteTo(tw);
            tw.Flush();
            rs.Close();
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            string msg;

            try {
                // Get the response from the server
                StreamReader reader = new StreamReader(resp.GetResponseStream());
                msg = reader.ReadToEnd();
                xmlReturn.LoadXml(msg);
            } catch (Exception e) {
                throw new Exception("Error posting to server: " + strURL, e);
            }
            return xmlReturn;
        }


        protected void Page_Load(object sender, EventArgs e) {
            try {
                XmlDocument xml = new XmlDocument();
                xml.LoadXml("<xml/>");
                xml.DocumentElement.SetAttribute("userid", "test");
                string strID = "userid";
                string strPassword = "password";

                xml.DocumentElement.SetAttribute("id", strID);
                xml.DocumentElement.SetAttribute("pw", strPassword);

                // post XML to /datasvc.aspx on this .NET project
                string strURL = Request.Url.ToString().Replace( "client", "datasvc" );

                xml.DocumentElement.SetAttribute("service", "hello");
                XmlDocument xmlResponse = this.postXml(xml, strURL, strID, strPassword);
                Response.Write(xmlResponse.DocumentElement.GetAttribute("content"));

                xml.DocumentElement.SetAttribute("service", "time");
                xmlResponse = this.postXml(xml, strURL, strID, strPassword);
                Response.Write(xmlResponse.DocumentElement.GetAttribute("content"));


            } catch (Exception ex) {
                Response.Write(ex.Message);

            }

        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-20
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 2022-11-21
    相关资源
    最近更新 更多