none
.net客户端如何访问带有ws-secruty的java开发的CXF的webservice RRS feed

  • 问题

  • 后台采用java开发的CXF的webservice,前台采用.net客户端(vs2010).

    webservice没加ws-secruty时,。net可以正常访问。

    CXF的webservice端加了传统的用户名令牌机制或者数字签证技术(X.509 Certificates)后,前台。net客户端不知如何访问?

    刚接触wcf,感觉配置比较复杂,网络上很多例子都是针对服务端和客户端都为WCF实现,请这里的老师指点一二,多谢。

    2011年7月30日 3:06

答案

  • 你需要在客户端配置文件中增加如下内容:

    <identity>
             <certificate encodedValue="AwAA...IgFHqYA==" />
    </identity>

     

    这是服务端证书的公钥信息.这个放到你的<endpoint></endpoint>中,用来同服务器协商安全和保护消息.

    当然也可以指定其它类型的identity,比如dns之类的,客户端可以先访问服务器去下载证书公钥.

    2011年8月2日 1:40

全部回复

  • 你可以使用VS2010添加服务引用来自动生成代码.

    ws-security实现的是消息级别的安全,你必须清楚的知道服务端是如何实现用户名令牌机制的,以及WCF在实现用户名密码验证方面有哪些基本模式和可自定义模式.

    在使用数据证书的时候,服务端如何使用证书,以及是否要求验证客户端证书.采用了何种密钥交换算法,又使用了那种加密算法对消息加密.

    2011年8月1日 2:35
  • 谢谢 DroidXgnaW的指点,我现在情况是这样:

    1,我在java webservice端加了传统的用户名令牌机制,beans.xml的安全配置如下:

    <bean id="wss4jInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
     <constructor-arg>
      <map>
       <entry key="action" value="UsernameToken" />
       <entry key="passwordType" value="PasswordText" />
       <entry key="user" value="Server" />
       <entry key="passwordCallbackClass" value="test.ServerPasswordCallback" />
      </map>
     </constructor-arg>
    </bean>

    test.ServerPasswordCallback的代码如下:

    public class ServerPasswordCallback implements CallbackHandler {

     public void handle(Callback[] callbacks) throws IOException,
       UnsupportedCallbackException {
      // TODO Auto-generated method stub
      WSPasswordCallback wspassCallback = (WSPasswordCallback) callbacks[0];
      System.out.println("Identifier:"+wspassCallback.getIdentifier());
      wspassCallback.setPassword("apmclientpass");
     }

    2.wcf客户端的app。config配置如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <bindings>
                <wsHttpBinding>
                    <binding name="HelloServiceImplServiceSoapBinding" >
                        <security mode="Message">
                             <message clientCredentialType="UserName"   algorithmSuite="Default" establishSecurityContext="true" />
                        </security>
                    </binding>
               </wsHttpBinding>
          </bindings>
         <client>
                <endpoint address="http://127.0.0.1:8080/services/helloService"
                    binding="wsHttpBinding" bindingConfiguration="HelloServiceImplServiceSoapBinding"
                    contract="ServiceRef.IHelloService" name="HelloServiceImplPort"
                       behaviorConfiguration="ClientCertificateBehavior"/>
        </client>
      <behaviors>
       <endpointBehaviors>
        <behavior name="ClientCertificateBehavior">
         <clientCredentials>
          <serviceCertificate>
           <authentication certificateValidationMode="None" />
          </serviceCertificate>
         </clientCredentials>
        </behavior>
       </endpointBehaviors>
      </behaviors>

    </system.serviceModel>
    </configuration>

    代码调用处为:

                ServiceRef.HelloServiceClient helloServerClient = new ServiceRef.HelloServiceClient("HelloServiceImplPort");
                helloServerClient.ClientCredentials.UserName.UserName = "apmclient";
                helloServerClient.ClientCredentials.UserName.Password = "apmclientpass";
                ServiceRef.customer c = helloServerClient.selectMaxLongNameStudent(c1, c2);
                MessageBox.Show("长度大的:" + c.name);

    3.结果是:java service端报错误:org.apache.ws.security.WSSecurityException: An error was discovered processing the <wsse:Security> header

    wcf client端报错误:无法打开安全通道,因为与远程终结点的安全协商已失败。这可能是由于用于创建通道的 EndpointAddress 中不存在 EndpointIdentity 或错误指定了 EndpointIdentity。请确认由 EndpointAddress 指定或暗示的 EndpointIdentity 正确标识了远程终结点。

    好像wcf client端提交的xml文件中的soap报文的 header部分少了<wsse:Security> ?我也不知道如何来正确配置wcf客户端?

    用java客户端调用可正常通过密码验证,且它提交的xml文件中在head部分包含了,“<soap:Header><wsse:Security。。。。”。

     

    2011年8月1日 7:54
  • 你需要在客户端配置文件中增加如下内容:

    <identity>
             <certificate encodedValue="AwAA...IgFHqYA==" />
    </identity>

     

    这是服务端证书的公钥信息.这个放到你的<endpoint></endpoint>中,用来同服务器协商安全和保护消息.

    当然也可以指定其它类型的identity,比如dns之类的,客户端可以先访问服务器去下载证书公钥.

    2011年8月2日 1:40
  • 谢谢DroidXgnaW的继续回复

    1.我加了    

    <identity>     

    <dns value="apmserver"/>    

    </identity>

    java service端依旧报错误:org.apache.ws.security.WSSecurityException: An error was discovered processing the <wsse:Security> header

    2.我改app.config ,其中authenticationMode="MutualCertificate",其它配置类似于当前网络上搜到的例子

    java webservice端报General security error (WSSecurityEngine: No crypto property file supplied for decryption)

    3.我打算java客户端调用java webservice;.net wcf 客户端调用 .net wcf webservice来避免此问题

    • 已建议为答案 Sezen Yuan 2012年7月9日 17:31
    • 取消建议作为答案 Sezen Yuan 2012年7月9日 17:31
    • 已建议为答案 Sezen Yuan 2012年7月9日 17:31
    • 取消建议作为答案 Sezen Yuan 2012年7月9日 17:32
    2011年8月2日 7:35
  • 终于搞定,多谢DroidXgnaW的回复。

    • 已建议为答案 Sezen Yuan 2012年7月9日 17:31
    2011年8月2日 14:13
  • 我也遇到了这个问题,可否分享一下WCF如何配置啊,我的cxf是基本的用户名验证
    2011年9月23日 8:44
  • 我的邮箱是 34812285@qq.com, 先谢了
    2011年9月23日 8:51