当前位置: 首页 > 知识库问答 >
问题:

如何在CXF中每次发送soap消息时使用ws-security信息?

萧伟兆
2023-03-14

我希望能够在cxf中每次发送soap消息时动态更改/设置ws-security信息。如何才能最好地做到这一点。

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

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

2)我认为最好但最困难。我应该怎么做?

我在考虑:a)jaxws客户端:创建我自己的入/出html" target="_blank">拦截器来截取消息,并根据消息所需的安全设置使用正确的(缓存的)WSS4JOutInterceptor拦截器。如果缓存中不存在WSS4JOutInterceptor拦截器,则会创建它(我可能最多缓存5个WSS4JOutInterceptor实例)。然而,当与@Webservice代理对话以创建和发送soap请求/消息时,我如何确定我的拦截器中需要哪些设置,这在应用程序的另一部分中是已知的。。。也许我可以通过JaxWsClientProxy向soap消息添加某种securityInfo对象,但是如何添加呢?。。。或者,我可以在发送/创建soap消息时设置拦截器,而此时安全信息仍然是已知的。这将是一个轻量级拦截器,包含所需的设置,链接到缓存的拦截器,根据设置进行选择。。。

b)超文本传输协议管道:使用ConduitSelector(从未使用过,但会发现),以便我能够选择正确的超文本传输协议管道,但我有与(a)中相同的问题:“如何确定我应该使用哪些设置”,因为它们在创建/发送肥皂剧消息时是已知的,拦截器稍后设置...可能我必须为每个发送消息设置一个管道选择器...

最后,上述内容成为一个大故事;),但我希望你能给我一些建议?

共有2个答案

计均
2023-03-14

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

嗨Ed,

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

AddNumbers port=(AddNumbers)service.getPort(portName, AddNumbers.class);((BindingProvider)port). getRequest estContext(). put(SecurityCon量.ENCRYPT_PROPERTIES,)。

尽管如此,如果您想在拦截器中执行此操作,您可以使用相同的技术通过消息属性传递必要的信息。

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

干杯,安德烈。

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

如果您这样做:((BindingProvider)port). getRequest estContext(). put("thread.local.request.context","true");

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

中的详细信息http://cxf.apache.org/faq.html#FAQ-JAXWSClientProxiestThreadSafe吗?

干杯,安德烈。

钱宇
2023-03-14

我发现org.apache.cxf包非常有助于避免我编写自定义类,并且能够坚持使用基本接口。

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

  • 使用JAX-WS或wsimport客户端

典型的(wsimport)客户端公共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。要传递的用户值,要使用的PW\U回调类,要使用的SIG\U PROP\U文件。

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

# 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" );
            }
        }        
    }
}

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

 类似资料:
  • 我们正在使用spring kafka 1.2.2。释放 我们想要的 1.一旦消息被消费并成功处理,就会在spring-kafka中提交偏移量。 我正在使用Manaul Commit/Ac认收它,它工作正常。 2.在任何异常的情况下,我们希望spring-kafka重新发送相同的消息。 我们对任何系统误差抛出RunTime异常,它由spring-kafka记录并且从未提交。 这很好,因为我们不希望它

  • 我试图读取来自CXF拦截器的SOAP错误消息,但我无法提取,我捕获了来自Fidler的响应 以下是菲德勒的回应 以下是我的代码 向客户端添加了FaultInterceptor

  • 我有一个Spring Boot服务器和一个客户端,它们使用STOMP通过Websockets连接。 我的用例是,每次向特定endpoint发出http请求时,我都想向客户机发送数据。我找到的所有教程,只展示了这种情况,客户端向“/hello”发送一些数据,服务器通过向“topic/greetings”发送数据做出反应: 我需要的是一个控制器方法,它无需消息映射即可发送数据。它应该只是在每次有人对e

  • 谁能给出一个简单的代码吗?我可以简单地进行HTTP调用吗?

  • 问题内容: 因此,我的Web应用程序需要身份验证,并且我有一个注册页面,如果该人员尝试使用数据库中已经存在的电子邮件进行注册,我想向他们显示错误消息。我正在尝试在html端使用以下代码执行此操作: 并在我的路线中执行以下操作: 我已经尝试通过以下方式设置配置: 但这给了我一个TypeError: 我真的很困惑,因为我知道我需要会话才能使Flash正常工作,但是会话似乎对我来说并不起作用。我还尝试通