【问题标题】:How to use ws-security info per sending soap message in CXF?如何在 CXF 中每次发送肥皂消息时使用 ws-security 信息?
【发布时间】:2012-12-05 13:36:52
【问题描述】:

我希望能够在 cxf 中动态更改/设置每个发送肥皂消息的 ws-security 信息。怎样才能最好地做到这一点。

详细信息:我想在运行时更改密钥库名称、密钥库别名、密码、主机名等设置,最好在每次发送消息时更改。 目前我正在使用:带有 WSS4JOutInterceptor 和 WSS4JInInterceptor 拦截器的 jaxws 客户端进行签名。我正在使用带有 tls 客户端参数的 http 管道进行 SSL/TLS 通信。 jaxws 客户端和 http 管道都在 spring 中配置,并且在 Spring 配置中设置了它们的配置,如密钥库名称、别名和密码。

我看到了选项: 1)我在运行时通过全局属性更改这些设置。 2) 我会根据发送消息更改这些设置(最好)。

2) 是可取的,但我认为是最困难的。 我该怎么做?

我在想: a) jaxws 客户端:制作我自己的进出拦截器来拦截消息,并根据该消息所需的安全设置使用正确的(缓存的)WSS4JOutInterceptor 拦截器。如果缓存中不存在 WSS4JOutInterceptor 拦截器,则会创建它(我可能缓存了最多 5 个 WSS4JOutInterceptor 实例)。 但是,当与@Webservice 代理交谈以创建和发送soap 请求/消息时,如何确定我的拦截器中需要哪些设置,因为这在应用程序的其他部分中是已知的...... 也许我可以通过 JaxWsClientProxy 将某种 securityInfo 对象添加到肥皂消息中,但是如何?... 或者,当仍然知道此安全信息时,也许我可以在发送/创建肥皂消息时设置拦截器。这将是一个包含所需设置的轻量级拦截器,链接到缓存的拦截器,根据设置选择...

b) http 管道:使用 ConduitSelector(从未使用过,但会发现),这样我就可以选择正确的 http 管道,但我遇到了与 (a) 中相同的问题:“如何确定哪个我应该使用的设置”,因为它们在创建/发送肥皂消息时已知,并且拦截器稍后设置...... 可能我必须为每个发送消息设置一个管道选择器..

最后上面变成了一个大故事;),但我希望你能给出一些建议吗?

【问题讨论】:

标签: java cxf


【解决方案1】:

我发现org.apache.cxf 包非常有助于让我不必编写自定义类并且能够坚持使用基本界面。

对于您的实例,该方法可能如下所示:

  • 使用JAX-WSwsimport 客户端
  • cxf WSS4JOutInterceptor 与动态属性一起使用
  • 使用动态 CallbackHandler 类访问密钥库

典型的 (wsimport'd) 客户端公共 API 可能如下所示:

public class SomeServiceClient
{

  public SomeService getSomeService( URL url )
  {

    SomeService_Service svc = new SomeService_Service();

    SomeService someService = svc.getSomeServicePort();

    Client client = ClientProxy.getClient( someService );
    Endpoint cxfEP = client.getEndpoint();

    Map<String, Object> outProps = new HashMap<String, Object>();
    outProps.put( WSHandlerConstants.ACTION, "Signature" );
    outProps.put( WSHandlerConstants.USER, "foo" );
    outProps.put( WSHandlerConstants.PW_CALLBACK_CLASS, SomeClientCallbackHandler.class.getName() );
    outProps.put( WSHandlerConstants.SIG_PROP_FILE, "client-sign.properties" );

    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor( outProps );

    cxfEP.getOutInterceptors().add( wssOut );

    return someService;
  }
}

您可以提供一些逻辑来确定要传递哪个WSHandlerConstants.USER 值、使用哪个PW_CALLBACK_CLASS 以及使用哪个SIG_PROP_FILE

属性文件可能如下所示。您可以简单地选择多个文件,或者您可以在类中动态添加这些属性:

# properties for accessing the java keystore using Merlin
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=bar
org.apache.ws.security.crypto.merlin.keystore.alias=foo
org.apache.ws.security.crypto.merlin.keystore.file=foobar.keystore

最后,您的CallbackHandler 需要提供您在密钥库中标识的证书别名的密码。这也可能包含一些动态逻辑。

public class SomeClientCallbackHandler implements CallbackHandler
{

    @Override
    public void handle( Callback[] callbacks ) throws IOException, UnsupportedCallbackException
    {
        for( Callback thisCallback : callbacks )
        {
            WSPasswordCallback pwcb = (WSPasswordCallback)thisCallback;
            String user = pwcb.getIdentifier();
            int usage = pwcb.getUsage();

            if( usage == WSPasswordCallback.SIGNATURE )
            {
                if( "foo".equals( user ) ) pwcb.setPassword( "bar" );
            }
        }        
    }
}

最后,与只做一次所需的工作相比,没有太多工作可以让这一切“动态”处理多个密钥库。这可能比编写自己的“输入”或“输出”拦截器更好。

【讨论】:

    【解决方案2】:

    这个问题的公认答案似乎是(来自http://www.mail-archive.com/users@cxf.apache.org/msg29804.html):

    嗨,埃德,

    正如我已经写过的,你甚至不需要拦截器来改变 特性。您可以通过发送消息在客户端中执行此操作:

    AddNumbers 端口 = (AddNumbers)service.getPort(portName, AddNumbers.class); ((BindingProvider)port).getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES, )。

    虽然,如果你想在拦截器中这样做,你可以通过 使用相同技术的消息属性的必要信息。

    在 CXF 中控制安全性的最标准和推荐的方法是 使用 WS-Policy。您还可以在运行时动态应用它。如果 这种方式对你来说很有趣,我可以提供更多信息 如何动态设置 WS-Policy。

    干杯,安德烈。

    (来自http://www.mail-archive.com/users@cxf.apache.org/msg29809.html):

    如果你这样做: ((BindingProvider)port).getRequestContext().put("thread.local.request.context", “真”);

    以后对 getRequestContext() 的调用将使用本地线程 请求上下文。这允许请求上下文是线程安全的。 (注意:响应上下文在 CXF 中始终是线程本地的)。

    详情在 http://cxf.apache.org/faq.html#FAQ-AreJAXWSclientproxiesthreadsafe%3F

    干杯,安德烈。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多