积极答复者
WCF security/policy 异常:{"Failed to assert identity with UsernameToken."}

问题
-
开发环境:.net framewor4.0 , VS2010, C#
下面是wsdl里安全策略部分:<?xml version="1.0" encoding="UTF-8"?>
<WL5G3N1:definitions targetNamespace="http://mysample.com.cn/" xmlns:WL5G3N0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:WL5G3N1="http://schemas.xmlsoap.org/wsdl/" xmlns:WL5G3N2="http://mysample.com.cn/" xmlns:WL5G3N3="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:UsingPolicy WL5G3N1:Required="true" /> <wsp:Policy WL5G3N0:Id="WS-Policy-WSSE-PasswordDigest"> <wssp:Identity xmlns:wssp="http://www.bea.com/wls90/security/policy"> <wssp:SupportedTokens> <wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken"> <wssp:UsePassword Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest" /> </wssp:SecurityToken> </wssp:SupportedTokens> </wssp:Identity>
<WL5G3N1:types> ...</WL5G3N1:types>
<WL5G3N1:message name="ValidateNewRegistrationOrderRequest"> ...</WL5G3N1:message>
<WL5G3N1:message name="ValidateNewRegistrationOrderResponse"> ...</WL5G3N1:message>
<WL5G3N1:portType name="ValidateNewRegistrationOrder"> ... </WL5G3N1:portType>
<WL5G3N1:binding name="ValidateNewRegistrationOrderHTTP" type="WL5G3N2:ValidateNewRegistrationOrder">
<WL5G3N3:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<WL5G3N1:operation name="ValidateNewRegistrationOrder">
<WL5G3N3:operation soapAction="urn:#ValidateNewRegistrationOrderOperation"/>
<WL5G3N1:input>
<wsp:Policy>
<wsp:PolicyReference URI="#WS-Policy-WSSE-PasswordDigest"/>
</wsp:Policy>
......
</WL5G3N1:input>
<WL5G3N1:output>
......
</WL5G3N1:output>
</WL5G3N1:operation>
</WL5G3N1:binding>
<WL5G3N1:service name="ValidateNewRegistrationOrder">
<WL5G3N1:port binding="WL5G3N2:ValidateNewRegistrationOrderHTTP" name="ValidateNewRegistrationOrder">
<WL5G3N3:address location="http://mysample:8080/ValidateNewRegistrationOrder/v1.0"/>
</WL5G3N1:port>
</WL5G3N1:service>
</WL5G3N1:definitions>
仿照下面的链接,我写了 CustomCredentials类,并完成 PasswordDigest 类型 的Usernametoken 。
http://stackoverflow.com/questions/896901/wcf-adding-nonce-to-usernametoken/20325151#20325151
具体代码如下:
public static ValidateNewRegistrationOrderClient CreateProxy(string url, string username, string password) { CustomBinding binding = new CustomBinding(); TransportSecurityBindingElement security = TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement(); security.IncludeTimestamp = false; security.AllowInsecureTransport = true; security.EnableUnsecuredResponse = true; security.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10; TextMessageEncodingBindingElement encoding = new TextMessageEncodingBindingElement(); encoding.MessageVersion = MessageVersion.Soap11WSAddressing10; HttpTransportBindingElement transport = new HttpTransportBindingElement(); binding.Elements.Add(security); binding.Elements.Add(encoding); binding.Elements.Add(transport); ValidateNewRegistrationOrderClient client = new ValidateNewRegistrationOrderClient(binding, new EndpointAddress(url)); client.ChannelFactory.Endpoint.Behaviors.Remove<System.ServiceModel.Description.ClientCredentials>(); client.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentials()); client.ClientCredentials.UserName.UserName = username; client.ClientCredentials.UserName.Password = password; return client; }
最终得到的请求报文头如下:
<s:Header> <a:Action> ... </a:Action> <a:MessageID> ...</a:MessageID> <a:ReplyTo> ... </a:ReplyTo> <a:To> ... </a:To> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <o:UsernameToken u:Id="uuid-3ef12f9d-75ab-407f-abe0-f833d063ac5b-1" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <o:Username>MyUserName</o:Username> <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"> EncryptedPassword </o:password> <o:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"> StringWith28Chars </o:Nonce> <u:Created>2013-11-26T12:21:22.627Z</u:Created> </o:UsernameToken> </o:Security> </s:Header>
我认为 Usernametoken 密码类型 Digest 还算是正确的。
但是:
1. 理论上,Nonce是唯一的随机数,网页上搜到的例子基本全都是24位 且 以双等号==结尾。
而我的 Nonce 和 Password 长度都是 28 字符。不知道这是否有影响?
2. 重点问题在 Identity , http://www.bea.com/wls90/security/policy 是 weblogicserver 的东西,只用于java的。
微软在 .net framework 4.5 里,对 ClientCredential 增加了 Identity 属性,
但我目前是 4.0 , 而且也不确定 4.5里的identity 是否就是我想解决的Identity.
3. 曾经也想尝试 不添加服务引用,而是直接 HttpWebRequest , 但也没完全想清楚......
希望大家给予建议和帮助,不胜感激额!
- 已编辑 MatrixZero 2013年12月4日 12:02
答案
-
DroidXgnaW 你好:
首先,谢谢您的回复。
我补充完整了几乎整个WSDL文件,并没有提到 关于 该 Token 的其他任何信息 。
现在拥有的内容:服务地址 (自然就有WSDL),UserName , Passowrd 。
我又该怎么去应用 SAML Token 呢?
盼复。看下 WCF 中 Claims-Based Authorization 的相关资料。
http://msdn.microsoft.com/zh-cn/library/aa355062(v=vs.100).aspx
上面是 4.5 之前的做法,4.5 以后,可以看下 Claims-aware WCF 的相关资料。
- 已标记为答案 Haixia_XieModerator 2013年12月9日 12:13
全部回复
-
DroidXgnaW 你好:
首先,谢谢您的回复。
我补充完整了几乎整个WSDL文件,并没有提到 关于 该 Token 的其他任何信息 。
现在拥有的内容:服务地址 (自然就有WSDL),UserName , Passowrd 。
我又该怎么去应用 SAML Token 呢?
盼复。看下 WCF 中 Claims-Based Authorization 的相关资料。
http://msdn.microsoft.com/zh-cn/library/aa355062(v=vs.100).aspx
上面是 4.5 之前的做法,4.5 以后,可以看下 Claims-aware WCF 的相关资料。
- 已标记为答案 Haixia_XieModerator 2013年12月9日 12:13