我已经成功创建了一个在不使用身份验证时正常工作的WS客户端。
但是,服务器(WebSphere)现在需要添加一个ws-security用户名令牌,而我很难做到这一点。生成的SOAP消息应该看起来像这样:
<soapenv:Envelope
xmlns:ns="http://foo.bar/1.0"
xmlns:ns1="http://www.witsml.org/schemas/140"
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">
<wsse:UsernameToken wsu:Id="UsernameToken-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>foo</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bar</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">foooooobar==</wsse:Nonce>
<wsu:Created>2010-01-25T13:09:24.860Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ns:fooBar>...</ns:fooBar>
</soapenv:Body>
我已下载并安装了Microsoft的WSE 3.0 SDK,并在我的Visual Studio 2005项目中添加了对DLL的引用。
我现在可以访问Microsoft.Web.Services3。*命名空间,但我目前难以理解如何继续。
客户端代码是由Web引用自动生成的,因此我只做了少量工作将消息发送到服务器 unauthenticated :
WS.FooResultHttpService ws = new WS.FooResultHttpService();
ws.Url = "http://foo.bar.baz";
ws.SendSomething(message);
我刚开始使用Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager
进行调查,但到目前为止,我还没有能够开始运行。
任何提示都会非常感激,因为我似乎无法在网上找到任何好的食谱。
谢谢!
答案 0 :(得分:14)
确保您的代理类继承自Microsoft.Web.Services3.WebServicesClientProtocol
。
您可以通过更改代理类本身,或使用带有/type:webClient
开关的wsewsdl3.exe通过命令行生成代理类来实现此目的。
然后您可以传递这样的凭据:
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Security.Tokens;
using Microsoft.Web.Services3.Security;
.
.
.
WS.FooResultHttpService ws = new WS.FooResultHttpService();
ws.RequestSoapContext.Security.Tokens.Add(new UsernameToken("blah", "blah", PasswordOption.SendPlainText));
这就是我过去在Studio 2008中使用WSE3.0所做的工作。希望有所帮助。
答案 1 :(得分:11)
在阅读wsanville's great answer之前,不幸地看到了它。
为了帮助其他人,我发布了我需要做的所有步骤才能使它与Visual Studio 2005一起使用:
YourWsNameHttpServiceWse
。这与运行wsewsdl3.exe SetClientCredential
。我最终在代码中做了几乎所有事情,而不是依赖于使用我的C#DLL构建的配置文件。代码最终看起来像这样:
FooBarHttpServiceWse wse = new FooBarHttpServiceWse();
wse.SetClientCredential(new UsernameToken(
"username",
"password",
PasswordOption.SendPlainText));
wse.SetPolicy(new FooBarPolicy());
wse.CallSomeServerFunction(yourRequest)
我创建了自己的政策,如下所示:
using Microsoft.Web.Services3.Design;
// ...
public class FooBarPolicy : Policy
{
public FooBarPolicy()
{
this.Assertions.Add(new UsernameOverTransportAssertion());
}
}
最后,WebSphere服务器响应表示消息寻址属性的必需标头不存在,并检查传出消息(使用漂亮的工具Fiddler)我看到了SOAP错误从服务器指示Action标头丢失。
我徒劳地尝试自己设置wsa:Action
元素:
using Microsoft.Web.Services3.Addressing;
// ...
wse.RequestSoapContext.Addressing.Action = new Action("CallSomeServerFunction");
问题是,即使我设置了一个动作,当它通过电线发送时,它也是空的。原来我必须打开WSE代理类并在那里编辑一个属性:
[System.Web.Services.Protocols.SoapDocumentMethodAttribute(
"---Edit this to set wsa:Action---",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
// ...
public SomeServerFunction(...)
在那之后,一切都很顺利。