قم بإزالة أقسام WS-WINDING / WS-Security من طلب عميل WSE 3.0
-
09-09-2019 - |
سؤال
لدي فئة وكيل خدمة الويب بسيطة C # التي قمت بإنشائها باستخدام Wsdl.exe. أنا استدعاء طريقة في خدمة الويب البعيدة، بما في ذلك مجموعة من رؤوس معالجة WS و WS-Security التي لا أريدها (وأن الخادم يختنق). هنا مثال على طلب الصابون الخام:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
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-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action></wsa:Action>
<wsa:MessageID>urn:uuid:22f12267-b162-4703-a451-2d1c5c5a619b</wsa:MessageID>
<wsa:To>http://example.com/wstest</wsa:To>
<wsse:Security>
<wsu:Timestamp wsu:Id="Timestamp-5c9f0ef0-ab45-421d-a633-4c4fad26d945">
<wsu:Created>2009-04-15T16:27:25Z</wsu:Created>
<wsu:Expires>2009-04-15T16:32:25Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>
<Func1 xmlns="http://example.com">
<arg_1 xmlns="">blah</arg_1>
<arg_2 xmlns="">blah2</arg_2></arg_2>
</Func1>
</soap:Body>
</soap:Envelope>
ولكن أنا لا أهتم بأشياء WS-TOOL / WS-Security. وبعد لقد فعلت شيئا لتضمينه. يبدو أن حزمة .NET WSE 3.0 تضيفها بشكل افتراضي. هل هناك أي طريقة للتخلص من هذه؟ لا أستطيع أن أرى أي خصائص على كائن وكيل الخاص بي الذي يسمح لي بإزالة هذه الأقسام. لقد حاولت:
proxyObject.Addressing.Clear();
proxyObject.Security.Clear();
هذه تسبب استثناء مرجعي فارغ عند استدعاء طريقة خدمة الويب الخاصة بي.
أريد أن تبدو طلب الصابون مثل هذا:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
</soap:Header>
<soap:Body>
<Func1 xmlns="http://example.com">
<arg_1 xmlns="">blah</arg_1>
<arg_2 xmlns="">blah2</arg_2></arg_2>
</Func1>
</soap:Body>
</soap:Envelope>
شكرا مقدما
المحلول
حسنا، انتهى بي الأمر باستخدام تقنية استخدمتها في الماضي. أنشأت فصول تنفذ Soapfilter. و detuctionassertion. والتي تسمح لي بتعديل XML RAW من طلب الصابون قبل إرساله. أدناه هو مثال:
public class MyPolicy : SoapFilter
{
public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
{
// Remove all WS-Addressing and WS-Security header info
envelope.Header.RemoveAll();
return SoapFilterResult.Continue;
}
}
public class MyAssertion : PolicyAssertion
{
public override SoapFilter CreateClientInputFilter(FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateClientOutputFilter(FilterCreationContext context)
{
return new MyPolicy();
}
public override SoapFilter CreateServiceInputFilter(FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateServiceOutputFilter(FilterCreationContext context)
{
return null;
}
}
ثم في محاكاة وكيل خدمة الويب الخاص بك، يمكنك تطبيق السياسة:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MyBinding", Namespace="http://example.com")]
public partial class MyWebClient : WebServicesClientProtocol {
// ... member variables here
/// <remarks/>
public MyWebClient()
{
this.Url = "http://example.com";
if ((this.IsLocalFileSystemWebService(this.Url) == true)) {
this.UseDefaultCredentials = true;
this.useDefaultCredentialsSetExplicitly = false;
}
else {
this.useDefaultCredentialsSetExplicitly = true;
}
// Apply policy here
Policy policy = new Policy();
policy.Assertions.Add(new MyAssertion());
this.SetPolicy(policy);
}
}
نصائح أخرى
لإزالة رأس العنوان الذي استخدمته الرمز أدناه في أحد التطبيقات الخاصة بي.
public override void SecureMessage(SoapEnvelope envelope, Security security)
{
//remove addressing Header from envelope
AddressingHeaders objAH = new AddressingHeaders(envelope);
objAH.RemoveXml(envelope);
//Add Wahtever security token you want to add.
security.Tokens.Add(bla-bla-bla);
}
انا إستعملت SecureMessage. وظيفة لأنني أردت إضافة الرموز الأمان، ولكن يمكن استخدام نفس الرمز في Prommipmessage. وظيفة.
أتساءل عما إذا كانت مشكلتك قد لا تكون لديها أيضا بن حلها ببساطة عن طريق عدم استخدام WSE؟
استنادا إلى الإجابة في هذه الصفحة، أضفت التعليمات البرمجية أدناه لإزالة رأس معين (بواسطة TagName) بشكل متكرر من XML.
Public Overrides Function ProcessMessage(ByVal envelope As SoapEnvelope) As SoapFilterResult
' Remove all WS-Addressing and WS-Security header info
RemoveTag(envelope.DocumentElement, "wsa:Action")
RemoveTag(envelope.DocumentElement, "wsa:MessageID")
RemoveTag(envelope.DocumentElement, "wsa:To")
Return SoapFilterResult.[Continue]
End Function
Private Sub RemoveTag(ByVal XE As System.Xml.XmlElement, ByVal TagName As String)
For Each N As XmlNode In XE
If N.ChildNodes.Count > 0 Then
RemoveTag(N, TagName)
End If
If N.Name = TagName Then
XE.RemoveChild(N)
End If
Next
End Sub
لقد وجدت أسهل طريقة لإزالة هذه العناوين والأمان هي تغيير تكوين خدمة الويب للاستخدام BasicHttpBinding
بدلا من WSHttp binding
.