java - 如何使用 CXF 获取发件人公钥?

标签 java soap cxf

我想弄清楚是否有可能获得调用方法的发送方的公钥作为方法参数。 如果我有一个 CXF 发布的具有非对称安全性的 SOAP 服务,是否可以通过某种方式告诉 CXF 使调用者的公钥可用于调用 Web 服务时调用的方法?

我希望能够将公钥定义为方法调用的额外参数,如下所示:

public interface Webservices{
    public ReturnVal soapMethod(SomeObject input, SomeOtherObject moreInput, PublicKey invokerPubKey)
}

返回的公钥不必作为 PublicKey 对象、字节数组或我可以使用的任何其他格式返回。

我也不太清楚这是否可以通过回调或拦截器来完成,但考虑到可以有多个处理线程,我不知道如何做。同样,我们将不胜感激。

我不一定需要 key 对象本身,获取别名或任何其他唯一标识符也可以,只要它能引导我找到存储的 key 。

最佳答案

SSL 协议(protocol)本身应该足以做到这一点。如果您使用 HTTPS 发布您的 Web 服务,那么您可以将服务器配置为向客户端询问它的证书(其中将包括它的公钥)。 为此,您可以检查以下 CXF configuration file .如您所见,有一部分说:

<sec:clientAuthentication want="true" required="true"/>

这告诉服务器,当客户端尝试建立连接时,它应该请求客户端的证书。

之后,您需要进行更多配置:

  1. 服务器应识别签署客户端证书的证书颁发机构。您可以在 server's trust store 中添加 CA .

  2. 客户端显然应该在某个地方拥有它的证书。如果是 Java 应用程序,您可以通过 adding the certificate in a keystore 来完成.

您还可以检查 complete CXF example .

现在您已准备好获取公钥!为此,我将假设您在 Java EE JAX-WS 应用程序中使用 CXF。

第一步是通过添加以下字段将 WebServiceContext 注入(inject)您的@WebService:

@Resource
private WebServiceContext webServiceContext;

然后您应该从 WebServiceContext 获取 HttpServletRequest:

MessageContext messageContext = webServiceContext.getMessageContext();
HttpServletRequest request = (HttpServletRequest)
              messageContext.get(MessageContext.SERVLET_REQUEST);

之后,您应该从请求中获取证书链:

X509Certificate[] certificates = (X509Certificate[])      
       request.getAttribute("javax.servlet.request.X509Certificate");

最后,您应该从中提取公钥:

公钥 publicKey = certificates[0].getPublicKey();

(客户端的证书应该是数组中的第一个)

WS 安全

如果您使用的是 WS-Security,您可以执行以下操作:

  1. 注册拦截器:
<jaxws:inInterceptors>
    <bean class="my.beloved.MyWSInterceptor"/>
</jaxws:inInterceptors>
  1. > 将 MyWSInterceptor 拦截器编码为 AbstractSoapInterceptor 的子类并实现 handleMessage(SoapMessage message) 方法:

公共(public)类 MyWSInterceptor 扩展 AbstractSoapInterceptor {

public void handleMessage(SoapMessage message) throws Fault {
    List<WSHandlerResult> results = CastUtils.cast((List<?>) message
        .get(WSHandlerConstants.RECV_RESULTS));
    for (WSHandlerResult wshr : results) {
        for (WSSecurityEngineResult wsser : wshr.getResults()) {
            PublicKey publicKey = wsser
                .get(WSSecurityEngineResult.TAG_PUBLIC_KEY);
        }
    }
}

有关 CXF 中 WS-Security 配置的更多信息,请查看 here .

关于java - 如何使用 CXF 获取发件人公钥?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28738843/

相关文章:

java - 带有评论框的文本组件

web-services - 将 CXF 与 Apache Camel 结合使用时,如何设置 WS-Addressing MessageId header ?

java - 在 jax-rs Web 服务中使用 java 接口(interface)的好处?

java - 使用CXF和maven将源代码注释导出到WSDL?

java - 如何测试ws-security?

java - 使用数组来决定谁是活跃玩家(回合制猜谜游戏)

java - 如何确定选项卡中 fragment 的 XML 布局?

java - WS响应解析我的xml字符串 '<'到 '&lt'

java - 我们可以在soapui中使用apache poi jar吗?

node.js - 如何在 React js 中进行 Soap 调用?