我正在为某些 STS 服务构建一个客户端,并且现在我正在尝试向 WCF 消息添加一个标头。在我对 RequestSecurityToken 的调用中,我必须包含一个 UsernameToken。
我不确定如何做到这一点。目前我定义了一个端点行为和一个消息检查器(花了我足够长的时间来发现这些......)。在后者的 BeforeSendRequest() 中,我创建了一个派生自 MessageHeader 的自定义类“Security”的对象。安全性包括 UsernameToken 的一个实例。
public class MessageInspector : IClientMessageInspector {
public object BeforeSendRequest(ref Message request, IClientChannel channel) {
Security uns = new Security();
uns.UsernameToken = new UsernameToken();
// ...
var Header = new MessageHeader<Security>(uns);
var untyped = Header.GetUntypedHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
request.Headers.Add(untyped);
return null;
}
}
public class Security : MessageHeader {
public UsernameToken UsernameToken = new UsernameToken();
public override string Name {
get { return "Security"; }
}
public override string Namespace {
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}
}
public class UsernameToken {
public String Username = "";
public Password Password = new Password();
}
这是正在序列化的内容
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">urn:RequestSecurityToken</Action>
<Security xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<UsernameToken xmlns="http://schemas.datacontract.org/2004/07/Tarifrechner.Kfz">
<Password>
<Type>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText</Type>
<password>******</password>
</Password>
<Username>******</Username>
</UsernameToken>
</Security>
</s:Header>
<s:Body />
</s:Envelope>
特别是 UsernameToken 的命名空间似乎是错误的。我知道它来自数据合同序列化,但我需要一个不同的命名空间。
这就是我希望序列化数据的样子
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="...">
<soap:Header>
<Security xmlns:q1="http://www.bipro.net/namespace" xsi:type="q1:UserNameSecurity"
xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<UsernameToken>
<Username>******</Username>
<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">******</Password>
</UsernameToken>
</Security>
<wsa:Action>urn:RequestSecurityToken</wsa:Action>
<wsse:Security>
<wsu:Timestamp wsu:Id="Timestamp-b9dd599d-5901-451d-8321-6a309091f273">
<wsu:Created>2012-03-11T16:02:56Z</wsu:Created>
<wsu:Expires>2012-03-11T16:07:56Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>
<RequestSecurityToken xmlns="http://schemas.xmlsoap.org/ws/2005/02/trust">
<TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</TokenType>
<RequestType>
http://schemas.xmlsoap.org/ws/2005/02/trust/Issue
</RequestType>
</RequestSecurityToken>
</soap:Body>
</soap:Envelope>
我的方法对吗?以及如何操作诸如标题详细信息的名称空间或数据是否被序列化为属性或元素之类的东西?
更新
正如 Ladislav 已经指出的那样,我不必自己实现像 UsernameToken 这样的类。我这样做只是因为我对 WCF 的了解非常有限。
到现在为止,我发现 WS2007HttpBinding 配置为使用 SecurityMode.TransportWithMessageCredential 并且将 EstablishSecurityContext 设置为 false 几乎可以生成我正在寻找的 XML。我怎么会知道的?
但是还有一个问题:我的请求有一个空的 body 元素,我想要生成的请求在 body 元素内具有一个 RequestSecurityToken 元素。有谁知道,我怎么能做到这一点?
使用 EstablishSecurityContext = true 有帮助,但同时将我的 Soap-Action 从所需的“urn:RequestSecurityToken”更改为不工作的“http://docs.oasis-open.org/ws-sx/ws-trust/200512 /RST/SCT”。
我很感激任何答案!
非常感谢!
比约恩