错误WCF客户端与消费的WS-Security UsernameToken的PasswordDigest认证方案轴2 Web服务 [英] Error in WCF client consuming Axis 2 web service with WS-Security UsernameToken PasswordDigest authentication scheme

查看:402
本文介绍了错误WCF客户端与消费的WS-Security UsernameToken的PasswordDigest认证方案轴2 Web服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WCF客户端连接到基于Java的Axis2 Web服务(我的控制范围之内)。它是关于拥有的WS-Security应用到它,我需要修复的.NET客户端。不过,我挣扎着提供正确的身份验证。据我所知,WSE 3.0可能更容易,但我会preFER没有恢复到过时的技术。

类似的问题(未解决),包括,<一个href=\"http://stackoverflow.com/questions/2368131/wcf-configuration-for-soap-plain-text-password-authentication-over-ssl\">this和<一个href=\"http://www.eggheadcafe.com/community/aspnet/2/10050148/consume-java-webservice-w.aspx\">this.

SOAP消息的是这样的:

 &LT; WSSE:用户名令牌&GT;
  &LT; WSSE:用户名&gt;&LT; - 删除 - &GT;&LT; / WSSE:用户名&gt;
  &LT; WSSE:密码Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\"><!--删除 - &GT;&LT; / WSSE:密码&GT;
  &LT; WSSE:随机数&GT;&LT; - 删除 - &GT;&LT; / WSSE:随机数&GT;
  &LT; WSSU:创建&GT; 2010-05-28T12:50:33.675 + 01:00&LT; / WSSU:创建&GT;
&LT; / WSSE:用户名令牌&GT;

不过,我的是这样的:

 &LT; S:页眉和GT;
&LT; H:安全的xmlns:H =htt​​p://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd的xmlns =HTTP://文档.oasis-open.org / WSS / 2004/01 /绿洲-200401-WSS-wssecurity-secext-1.0.xsd的xmlns:XSI =http://www.w3.org/2001/XMLSchema-instance的xmlns: XSD =htt​​p://www.w3.org/2001/XMLSchema&GT;&LT /小时:安全和GT;
&LT;○:安全小号:mustUnderstand属性=1的xmlns:O =htt​​p://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&GT ;
&LT; U:时间戳U:n =_ 0&GT;
&LT; U:创建&GT; 2010-06-23T10:31:23.441Z&LT; / U:创建&GT;
&LT; U:过期&GT; 2010-06-23T10:36:23.441Z&LT; / U:过期&GT;
&LT; / U:时间戳&GT;
&LT;○:用户名令牌U:n =UUID-d329b3b2-6a1f-4882-aea6-ec6b8a492de7-1&GT;
&LT;○:用户名&gt;
&LT;! - 删除 - &GT;
&LT; / O:用户名&gt;
&LT;○:密码&GT;
&LT;! - 删除 - &GT;
&LT; / O:密码&GT;
&LT; / O:用户名令牌&GT;
&LT; / O:安全和GT;
&LT; / S:页眉和GT;

我的客户是这样的:
附:注意:在要求 SecurityHeaderType参数。那是什么?

 公共MyAck sendRequest将(MyRequest要求)
{
 RemoteServicePortTypeClient客户端=新RemoteServicePortTypeClient(); client.ClientCredentials.UserName.UserName =JAY;
 client.ClientCredentials.UserName.Password =和;    //是在两个不同的凭证类型之间的差值Δθ
    //client.ClientCredentials.HttpDigest.ClientCredential.UserName =沉默;
    //client.ClientCredentials.HttpDigest.ClientCredential.Password =BOB; SecurityHeaderType SHT =新SecurityHeaderType();
 //sht.Any = ???; //我如何使用这个?
 //sht.AnyAttr = ???; //我如何使用这个? // SecurityHeaderType是一个必需的参数
 返回client.RemoteServiceOperation_Provider(SHT,请求);
}

电流结合如下:

 &LT;&basicHttpBinding的GT;
    &LT;绑定名称=CustomBinding&GT;
        &LT;安全模式=TransportWithMessageCredential&GT;
            &LT;运输clientCredentialType =无&GT;&LT; /运输及GT;
            &LT;消息clientCredentialType =用户名/&GT;
        &LT; /安全&GT;
    &LT; /&结合GT;
&LT; / basicHttpBinding的&GT;

我也试了一个自定义绑定,并得到了类似的错误:

 &LT; customBinding&GT;
  &LT;绑定名称=myCustomBindingConfig&GT;
    &LT;安全authenticationMode =UserNameOverTransport
      messageSecurityVersion=\"WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11\"
      securityHeaderLayout =严格
      includeTimestamp =false的&GT;&LT; /安全&GT;
    &LT; textMessageEncoding messageVersion =Soap11&GT;&LT; / textMessageEncoding&GT;
    &LT; httpsTransport /&GT;
  &LT; /&结合GT;
&LT; / customBinding&GT;

和端点(地址发生明显变化......):

 &LT;端点地址=htt​​ps://www.somecompany.com/uat/axis/services/RemoteServiceOperation_Provider
      绑定=basicHttpBinding的bindingConfiguration =CustomBinding
      合同=RemoteService.RemoteServicePortType
      NAME =RemoteService_UAT/&GT;

这是返回的自定义错误如下:

 &LT;&ErrorID中GT; 0℃; / ErrorID中&GT;
&LT;错误类型&GT;&意外LT; /错误类型&GT;
!&LT; ErrorDescription中&GT;&LT; [CDATA [数组索引超出范围:0]]&GT;&LT; / ErrorDescription中&GT;
&LT;&时间戳GT; 2010-06-23T13:28:54Z&LT; /时间戳&GT;

我读过很多关于自定义标题,令牌,绑定和我的大脑是完全糊涂了。任何人都可以提出一个循序渐进的过程在正确的格式发送邮件?

似乎是未来路向WCF,使用定制令牌,但如何应在应用所需的摘要和随机数?

任何帮助的欢迎。

更新

我有一些有限的成功。我用Microsoft.Web.Services3库来创建具有正确摘要的用户名令牌。我然后创建了自己的定制行为,并在BeforeSendRequest方法我已经做了注射头以下内容:

 对象IClientMessageInspector.BeforeSendRequest(REF System.ServiceModel.Channels.Message要求,System.ServiceModel.IClientChannel频道)
{
    用户名令牌UT =新的UsernameToken(USERNAME,密码,PasswordOption.SendHashed把);    的XmlElement securityElement = ut.GetXml(新的XmlDocument());    的MessageHeader myHeader = MessageHeader.CreateHeader(安全,http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd,securityElement,FALSE);
    request.Headers.Add(myHeader);    返回Convert.DBNull;
}

我添加行为,就像这样:

  CustomBehavior行为=新CustomBehavior(USERNAME,密码);
client.Endpoint.Behaviors.Add(行为);

我现在能看到头去跨越:

 &LT; S:页眉和GT;
&LT;安全的xmlns =htt​​p://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&GT;
&LT; WSSE:用户名令牌WSU:ID =SecurityToken-c6aeb72d-4d36-4650-abd3-33cc66caac6d的xmlns:WSSE =htt​​p://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&GT;
&LT; WSSE:用户名&gt;
&LT;! - 删除 - &GT;
&LT; / WSSE:用户名&gt;
&LT; WSSE:密码&GT;
&LT;! - 删除 - &GT;
&LT; / WSSE:密码&GT;
&LT; WSSE:随机数&GT;
&LT;! - 删除 - &GT;
&LT; / WSSE:随机数&GT;
&LT; WSU:创建&GT; 2010-06-24T16:23:58Z&LT; / WSU:创建&GT;
&LT; / WSSE:用户名令牌&GT;
&LT; /安全和GT;
&LT; / S:页眉和GT;

但我得到的错误:

 &LT; soapenv:故障&GT;
&LT;故障code的xmlns =&GT; soapenv:服务器16; /故障code&GT;
&LT; faultstring的xmlns =&GT; WSDoAllReceiver:安全处理失败;嵌套的异常是:
    org.apache.ws.security.WSSecurityException:一般安全错误(WSSecurityEngine:回调提供了没有密码:USERNAME)LT; / faultstring&GT;
&LT; faultactor的xmlns =&GT;金塔:Remote_Provider&LT; / faultactor&GT;
&LT;详细的xmlns =&GT;
&LT; CUSTOMError的xmlns =金塔:customerror:V01&GT;
&所述; ErrorID中大于0&下; / ErrorID中&GT;
&LT;错误类型&GT;&意外LT; /错误类型&GT;
&所述; ErrorDescription中&GT;&下; [CDATA [WSDoAllReceiver:安全处理失败;嵌套的异常是:
    org.apache.ws.security.WSSecurityException:一般安全错误(WSSecurityEngine:回调提供了没有密码:USERNAME)]]&GT;&LT; / ErrorDescription中&GT;
&LT;&时间戳GT; 2010-06-24T17:23:59Z&LT; /时间戳&GT;
&LT; / CUSTOMError&GT;
&LT; /详情&GT;
&LT; / soapenv:故障&GT;

有似乎是一个丢失的类型密码节点上的属性:

<$p$p><$c$c>Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\"

不过,我不知道,如果安全跟踪和日志记录设置毯取出的属性和这些节点的内容。我已经尝试使用 logKnownPii 的诊断日志记录设置,但安全信息保持模糊。在那一个什么想法?


解决方案

我可以证实,从我的问题UPDATE实际工作:

 对象IClientMessageInspector.BeforeSendRequest(REF System.ServiceModel.Channels.Message要求,System.ServiceModel.IClientChannel频道)
{
    用户名令牌UT =新的UsernameToken(USERNAME,密码,PasswordOption.SendHashed把);    的XmlElement securityElement = ut.GetXml(新的XmlDocument());    的MessageHeader myHeader = MessageHeader.CreateHeader(安全,http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd,securityElement,FALSE);
    request.Headers.Add(myHeader);    返回Convert.DBNull;
}

和客户端:

  CustomBehavior行为=新CustomBehavior(USERNAME,密码);
client.Endpoint.Behaviors.Add(行为);

该错误消息无关。安全报头可以与一个非常简单的basicHttpBinding的

 &LT;&basicHttpBinding的GT;
  &LT;绑定名称=BasicSOAPBinding&GT;
      &LT;安全模式=运输/&GT;
  &LT; /&结合GT;
&LT; / basicHttpBinding的&GT;

在这一行动code样品可以在我的博客上找到:的http://benpowell.org/supporting-the-ws-i-basic-profile-password-digest-in-a-wcf-client-proxy/

I have a WCF client connecting to a Java based Axis2 web service (outside my control). It is about to have WS-Security applied to it, and I need to fix the .NET client. However, I am struggling to provide the correct authentication. I am aware that WSE 3.0 might make it easier, but I would prefer not to revert to an obsolete technology.

Similar issues (unsolved), include this, this and this.

The SOAP message should look like this:

<wsse:UsernameToken>
  <wsse:Username><!-- Removed--></wsse:Username> 
  <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"><!-- Removed--></wsse:Password> 
  <wsse:Nonce><!-- Removed--></wsse:Nonce> 
  <wssu:Created>2010-05-28T12:50:33.675+01:00</wssu:Created> 
</wsse:UsernameToken>

However, mine looks like this:

<s:Header>
<h:Security xmlns:h="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"></h:Security>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2010-06-23T10:31:23.441Z</u:Created>
<u:Expires>2010-06-23T10:36:23.441Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-d329b3b2-6a1f-4882-aea6-ec6b8a492de7-1">
<o:Username>
<!-- Removed-->
</o:Username>
<o:Password>
<!-- Removed-->
</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>

My client looks like this: P.S. Note the required SecurityHeaderType param. What is that?

public MyAck SendRequest(MyRequest request)
{
 RemoteServicePortTypeClient client = new RemoteServicePortTypeClient();

 client.ClientCredentials.UserName.UserName = "JAY";
 client.ClientCredentials.UserName.Password = "AND";

    // what is the difference between the two different Credential types??
    //client.ClientCredentials.HttpDigest.ClientCredential.UserName = "SILENT";
    //client.ClientCredentials.HttpDigest.ClientCredential.Password = "BOB";

 SecurityHeaderType sht = new SecurityHeaderType();
 //sht.Any = ???; // How do I use this???
 //sht.AnyAttr = ???; // How do I use this ???

 // SecurityHeaderType is a required parameter
 return client.RemoteServiceOperation_Provider(sht, request);
}

Current binding is as follows:

<basicHttpBinding>
    <binding name="CustomBinding">
        <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None"></transport>
            <message clientCredentialType="UserName" />
        </security>
    </binding>
</basicHttpBinding>

I've also tried a custom binding and got a similar error:

<customBinding>
  <binding name="myCustomBindingConfig">
    <security authenticationMode="UserNameOverTransport"
      messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11"
      securityHeaderLayout="Strict"
      includeTimestamp="false"></security>
    <textMessageEncoding messageVersion="Soap11"></textMessageEncoding>
    <httpsTransport />
  </binding>
</customBinding>

And endpoint (Address obviously changed...):

<endpoint address="https://www.somecompany.com/uat/axis/services/RemoteServiceOperation_Provider"
      binding="basicHttpBinding" bindingConfiguration="CustomBinding"
      contract="RemoteService.RemoteServicePortType"
      name="RemoteService_UAT" />

The custom fault that is being returned is as follows:

<ErrorID>0</ErrorID>
<ErrorType>UNEXPECTED</ErrorType>
<ErrorDescription><![CDATA[Array index out of range: 0]]></ErrorDescription>
<TimeStamp>2010-06-23T13:28:54Z</TimeStamp>

I've read lots about custom headers, tokens, bindings and my brain is completely confused. Can anyone suggest a step by step process for sending the message in the right format?

This appears to be the way forward for WCF, using custom tokens, but how should one apply the digest and nonce as required?

Any help welcomed.

UPDATE

I've had some limited success. I've used the Microsoft.Web.Services3 library to create a UsernameToken with the correct digest. I've then created my own custom behavior and in the BeforeSendRequest method I've done the following to inject the header:

object IClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
    UsernameToken ut = new UsernameToken("USERNAME", "PASSWORD", PasswordOption.SendHashed);

    XmlElement securityElement = ut.GetXml(new XmlDocument());

    MessageHeader myHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", securityElement, false);
    request.Headers.Add(myHeader);

    return Convert.DBNull;
}

I add the behavior like so:

CustomBehavior behavior = new CustomBehavior("USERNAME", "PASSWORD");
client.Endpoint.Behaviors.Add(behavior);

I can now see the headers going across:

<s:Header>
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="SecurityToken-c6aeb72d-4d36-4650-abd3-33cc66caac6d" 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">
<wsse:Username>
<!-- Removed-->
</wsse:Username>
<wsse:Password>
<!-- Removed-->
</wsse:Password>
<wsse:Nonce>
<!-- Removed-->
</wsse:Nonce>
<wsu:Created>2010-06-24T16:23:58Z</wsu:Created>
</wsse:UsernameToken>
</Security>
</s:Header>

But I'm getting the error:

<soapenv:Fault>
<faultcode xmlns="">soapenv:Server</faultcode>
<faultstring xmlns="">WSDoAllReceiver: security processing failed; nested exception is: 
    org.apache.ws.security.WSSecurityException: General security error (WSSecurityEngine: Callback supplied no password for: USERNAME)</faultstring>
<faultactor xmlns="">urn:Remote_Provider</faultactor>
<detail xmlns="">
<CUSTOMError xmlns="urn:customerror:v01">
<ErrorID>0</ErrorID>
<ErrorType>UNEXPECTED</ErrorType>
<ErrorDescription><![CDATA[WSDoAllReceiver: security processing failed; nested exception is: 
    org.apache.ws.security.WSSecurityException: General security error (WSSecurityEngine: Callback supplied no password for: USERNAME)]]></ErrorDescription>
<TimeStamp>2010-06-24T17:23:59Z</TimeStamp>
</CUSTOMError>
</detail>
</soapenv:Fault>

There appears to be a missing Type attribute on the password node:

Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"

However, I'm not sure if the security tracing and logging settings are blanket removing the attributes and content of those nodes. I've attempted to use the logKnownPii setting in the diagnostics logging, but the security information remains obscured. Any ideas on that one?

解决方案

I can confirm that the UPDATE from my question actually works:

object IClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
    UsernameToken ut = new UsernameToken("USERNAME", "PASSWORD", PasswordOption.SendHashed);

    XmlElement securityElement = ut.GetXml(new XmlDocument());

    MessageHeader myHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", securityElement, false);
    request.Headers.Add(myHeader);

    return Convert.DBNull;
}

And the client:

CustomBehavior behavior = new CustomBehavior("USERNAME", "PASSWORD");
client.Endpoint.Behaviors.Add(behavior);

The error message was unrelated. The security header works with a very simple basicHttpBinding:

<basicHttpBinding>
  <binding name="BasicSOAPBinding">
      <security mode="Transport" />
  </binding>
</basicHttpBinding>

Code sample of this in action can be found on my blog: http://benpowell.org/supporting-the-ws-i-basic-profile-password-digest-in-a-wcf-client-proxy/

这篇关于错误WCF客户端与消费的WS-Security UsernameToken的PasswordDigest认证方案轴2 Web服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆