Authentication JAX-WS客户端CXF WS策略问题

Authentication JAX-WS客户端CXF WS策略问题,authentication,cxf,jax-ws,Authentication,Cxf,Jax Ws,我必须实现一个JAX-WS客户机,它使用来自外部合作伙伴的服务。我使用apachecxf。该服务在wsdl中定义了两个用于身份验证的WS-Policy-KerberosToken和UsernameToken。由于服务来自外部合作伙伴,因此无法更改 问题:Kerberos身份验证失败,因为我想使用 简单的UsernameToken身份验证 WSLD策略部分: <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy

我必须实现一个JAX-WS客户机,它使用来自外部合作伙伴的服务。我使用apachecxf。该服务在wsdl中定义了两个用于身份验证的WS-Policy-KerberosToken和UsernameToken。由于服务来自外部合作伙伴,因此无法更改

问题:Kerberos身份验证失败,因为我想使用 简单的UsernameToken身份验证

WSLD策略部分:

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
  wsu:Id="SecurityServiceUsernameUnsecureTransportPolicy">
  <wsp:ExactlyOne>
  <wsp:All>
    <sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    <wsp:Policy>
      <sp:KerberosToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
      <wsp:Policy>
        <sp:WssGssKerberosV5ApReqToken11/>
      </wsp:Policy>
      </sp:KerberosToken>
    </wsp:Policy>
    </sp:SupportingTokens>
  </wsp:All>
  <wsp:All>
    <sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    <wsp:Policy>
      <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
      <wsp:Policy>
        <sp:WssUsernameToken10/>
      </wsp:Policy>
      </sp:UsernameToken>
    </wsp:Policy>
    </sp:SupportingTokens>
  </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>
正如我所理解的,-标记意味着,如果任何一个策略被完全填充,那么继续。但是CXF甚至没有尝试填充UsernameToken-Policy

如果我为KerberosToken删除-Block,那么身份验证工作正常,但在生产中这是不可能的

有什么提示吗?如果wsdl或我的方法中有错误,请让我知道。请详细说明,我是这个领域的新手


提前谢谢

CXF不在出站端处理多个策略选项以确保安全,只在入站端处理。因此,您唯一的选择是将策略收紧为Kerberos或UsernameToken,具体取决于您希望客户端使用的策略

几天后,我找到了一个解决这个问题的方法——不称之为解决方案-

首先,旧版本: CXF生成了一个类ExampleWS\u服务和一个相应的接口ExampleWS。因此,我使用ExampleWS_服务设置所有内容并调用该服务:

//创建端口 URL URL=新URL config.getSchema、config.getHost、config.getPort、config.getPath; ExampleWS\u服务=新的ExampleWS\u服务url; ExampleWS-port=service.getExampleWSPort; //添加身份验证信息 Client Client=ClientProxy.getClient端口; 端点cxfEndpoint=client.getEndpoint; cxfEndpoint.put SecurityConstants.USERNAME,USERNAME; cxfEndpoint.put SecurityConstants.PASSWORD,PASSWORD; ... //调用服务 port.doSomething[数据]; 解决办法: 我切换到JaxWsProxyFactoryBean并设置所有内容。在这种情况下,需要一个WSS4JOutInterceptor将身份验证信息放入请求头中。一些代码:

URL URL=新URL config.getSchema、config.getHost、config.getPort、config.getPath; JaxWsProxyFactoryBean工厂=新的JaxWsProxyFactoryBean; factory.setServiceClass ExampleWS.class; factory.setAddress url.toString; 工厂.setBindingIdhttp://schemas.xmlsoap.org/wsdl/soap12/ ; ExampleWS-port=ExampleWS-factory.create; //使用WSS4JOutInterceptor添加身份验证信息 Client Client=ClientProxy.getClient端口; 端点cxfEndpoint=client.getEndpoint; Map outProps=新的HashMap; outProps.put WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME\u令牌; outProps.put WSHandlerConstants.USER,用户名; outProps.put WSHandlerConstants.PASSWORD\u类型,passwordType; outProps.put WSHandlerConstants.PW_CALLBACK_REF[javax.security.auth.CALLBACK.CallbackHandler的实例]; WSS4JOutInterceptor wssOut=新WSS4JOutInterceptor outProps; cxfEndpoint.getoutiterceptors.add wssOut; ... //调用服务 port.doSomething[数据]; 我不知道为什么这种变通方法确实有效,但它确实:-
也许你们中的某个人能给我这样的启示。

谢谢科尔姆·奥海吉塔伊!有没有办法告诉客户机忽略此策略,只发送一个UsernameToken请求?我无法收紧策略,因为服务器端由外部合作伙伴定义。这可能会帮助您:。默认情况下,选择了第一个策略选项,但可能有一种方法可以配置它。Thx Colm O heigerattaigh!我会调查一下的。除此之外,我还找到了一个解决办法。也许你可以给这个解决方案一些优点或缺点。
public void addAuthenticationProperties( Endpoint endpoint ) {
  endpoint.put( SecurityConstants.USERNAME, userName );
  endpoint.put( SecurityConstants.PASSWORD, password );
}