Apache CXF的WS-Security

时间:2014-09-02 14:43:22

标签: cxf ws-security

我尝试使用WS-Security实现CXF端点并接收soapUI发送的请求。 UsernameToken的密码存储在计划文本中。我只对接收请求感兴趣。

我使用ServiceMix 5.0.0与CXF 2.7.10和Camel 2.12.3。

WSDL文件中的policy元素:

  <wsp:Policy wsu:Id="MyPolicy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:TransportBinding
          xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:TransportToken>
              <wsp:Policy>
                <sp:HttpsToken RequireClientCertificate="false" />
              </wsp:Policy>
            </sp:TransportToken>
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:Basic256 />
              </wsp:Policy>
            </sp:AlgorithmSuite>
            <sp:Layout>
              <wsp:Policy>
                <sp:Lax />
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp />
          </wsp:Policy>
        </sp:TransportBinding>
        <sp:SignedSupportingTokens
          xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:UsernameToken
              sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
              <wsp:Policy>
                <sp:WssUsernameToken10 />
              </wsp:Policy>
            </sp:UsernameToken>
          </wsp:Policy>
        </sp:SignedSupportingTokens>
        <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy />
        </sp:Wss10>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

soapUI生成的SOAP消息:

<wsse:Security soapenv:mustUnderstand="1"
  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:UsernameToken wsu:Id="UsernameToken-0784752F597FAC191C140966645160280">
    <wsse:Username>foo</wsse:Username>
    <wsse:Password
      Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bar</wsse:Password>
    <wsse:Nonce
      EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">8C0iYAOWi3b+EgfDaY6n+Q==</wsse:Nonce>
    <wsu:Created>2014-09-02T14:00:51.602Z</wsu:Created>
  </wsse:UsernameToken>
</wsse:Security>

我添加到CXF端点In拦截器的WSS4JInInterceptor拦截器。这是我唯一明确添加的拦截器。

  private WSS4JInInterceptor getWssInInterceptor() {
    Map<String, Object> propertiesMap = new HashMap<String, Object>();
    propertiesMap.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
    propertiesMap.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
    propertiesMap.put(WSHandlerConstants.USER, "bar");
    propertiesMap.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName());
    return new WSS4JInInterceptor(propertiesMap);
  }

ServerPasswordCallback.class

public class ServerPasswordCallback implements CallbackHandler {

  @Override
  public void handle(Callback[] callbacks) throws IOException,
      UnsupportedCallbackException {

    for (int i = 0; i < callbacks.length; i++) {

      WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

      if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) {
        if (pc.getIdentifier().equalsIgnoreCase("foo"))
          pc.setPassword("bar");
      }
    }

  }

}

我使用soapUI向服务器发送请求,但我在ServiceMix的日志中得到了这个:

2014-09-02 17:00:44,630 | WARN  | qtp32763811-5522 | PhaseInterceptorChain            | ?                                   ? | 129 - org.apache.cxf.cxf-api - 2.7.10 | Interceptor for {http://localhost/incoming}MyService#{http://localhost/incoming}IncomingChannel has thrown exception, unwinding now
org.apache.cxf.ws.policy.PolicyException: These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportBinding
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}IncludeTimestamp
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}Layout
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SignedSupportingTokens
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}UsernameToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}Wss10
        at org.apache.cxf.ws.policy.AssertionInfoMap.checkEffectivePolicy(AssertionInfoMap.java:179)[161:org.apache.cxf.cxf-rt-ws-policy:2.7.10]
        at org.apache.cxf.ws.policy.PolicyVerificationInInterceptor.handle(PolicyVerificationInInterceptor.java:101)[161:org.apache.cxf.cxf-rt-ws-policy:2.7.10]
        at org.apache.cxf.ws.policy.AbstractPolicyInterceptor.handleMessage(AbstractPolicyInterceptor.java:44)[161:org.apache.cxf.cxf-rt-ws-policy:2.7.10]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[129:org.apache.cxf.cxf-api:2.7.10]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[129:org.apache.cxf.cxf-api:2.7.10]

问:

如果在soapUI中创建的请求中使用了错误的凭据,我得到了预期的异常,那没关系,但是如何在服务器端满足这些策略呢?我在哪里可以找到关于这些策略断言的一些文档/示例?

谢谢!

1 个答案:

答案 0 :(得分:3)

您根本不需要添加“WSS4JInInterceptor”。当您拥有WS-SecurityPolicy时,WSS4JInInterceptor不适用。在这种情况下,CXF负责为您设置所有拦截器。您只需提供一些配置参数作为JAX-WS属性。

以下是春季的一些例子:

https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob_plain;f=systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ut/server.xml;hb=HEAD

通常,您只需要为此(UsernameToken)用例提供CallbackHandler(“ws-security.callback-handler”)。

BTW请求与策略不匹配,因为它不包含时间戳。因此,要么删除“IncludeTimestamp”策略,要么在SOAP-UI中为请求添加一个。

科尔姆。