JAX-WS 通过 WS-Security 和 WS-Addressing 使用 Web 服务

2023-11-25

我正在尝试使用 JAX-WS (Metro) 开发一个独立的 Java Web 服务客户端,该客户端使用 WS-Security 和用户名令牌身份验证(密码摘要、随机数和时间戳)和时间戳验证以及基于 SSL 的 WS-Addressing。

我必须使用的 WSDL 没有定义任何安全策略信息。当 WSDL 不包含此信息时,我一直无法准确地弄清楚如何添加此标头信息(正确的方法)。我发现的大多数使用 Metro 的示例都围绕着使用 Netbeans 从 WSDL 自动生成它,这对我没有任何帮助。我研究过 WSIT、XWSS 等,但没有太多清晰度或方向。 JBoss WS Metro 看起来也没什么运气。

有人有这样做的经验或对如何完成这项任务有建议吗?即使为我指明正确的方向也会有所帮助。除了必须基于 Java 之外,我不限于特定技术。


我最终确实解决了这个问题,但我走了另一个方向。我的解决方案是使用 CXF 2.1 及其 JAX-WS 实现,将 CXF 的强大功能与我已有的现有 Spring 基础设施相结合。一开始我很怀疑,因为 CXF 需要大量的 jar,但最终它提供了最好、最简单的解决方案。

改编一个例子用于客户端配置的 CXF 网站,我在 spring 中使用了自定义 CXF JAXWS 命名空间,并使用 Out Interceptor 进行用户名令牌身份验证(密码摘要、随机数和时间戳)和时间戳验证。完成这项工作的唯一其他步骤是创建我自己的密码回调处理程序,该处理程序针对每个出站 SOAP 请求执行。

对于 SSL 配置,我再次转向CXF 及其通过管道的 SSL 支持,虽然我永远无法使 SSL 与特定的 http:conduit 名称一起工作,但我必须使用不建议用于生产环境的通用名称。

下面是我的配置文件的示例。

弹簧配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:sec="http://cxf.apache.org/configuration/security"
    xmlns:http="http://cxf.apache.org/transports/http/configuration"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cxf="http://cxf.apache.org/core"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
    http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">

    <context:property-placeholder location="meta/my.properties" />
    <context:component-scan base-package="com.foo" />

    <import resource="remoting.xml" />
    <jaxws:client id="myWebService" address="${my.endpointAddress}"
                  serviceClass="com.foo.my.ServicePortType">

<!-- Testing only, adds logging of entire message in and out -->
<jaxws:outInterceptors>
    <ref bean="TimestampUsernameToken_Request" />
    <ref bean="logOutbound" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
        <ref bean="logInbound" />
    </jaxws:inInterceptors>
    <jaxws:inFaultInterceptors>
        <ref bean="logOutbound" />
    </jaxws:inFaultInterceptors>

<!-- Production settings -->
<!--
    <jaxws:outInterceptors> <ref bean="TimestampUsernameToken_Request" />
    </jaxws:outInterceptors>
    -->
</jaxws:client >



<!--
    CXF Interceptors for Inbound and Outbound messages
    Used for logging and adding Username token / Timestamp Security Header to SOAP message
-->
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

<bean id="TimestampUsernameToken_Request" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
    <constructor-arg>
        <map>
            <entry key="action" value="UsernameToken Timestamp" />
            <entry key="user" value="${my.group}.${my.userId}" />
            <entry key="passwordType" value="PasswordDigest" />
            <entry key="passwordCallbackClass" value="com.foo.my.ClientPasswordHandler" />
        </map>
    </constructor-arg>
</bean>

<!--
    http:conduit namespace is used to configure SSL using keystores, etc
    *.http-conduit works but CXF says its only supposed to be for temporary use (not production),
    well until the correct way works, we're going to use it.
-->
<http:conduit name="*.http-conduit">
    <http:tlsClientParameters   
                  secureSocketProtocol="SSL">
                  <!--
          <sec:trustManagers>
        <sec:keyStore type="JKS"
                         password="${my.truststore.password}"
                         file="${my.truststore.file}" />
                  </sec:trustManagers>
                  -->
                  <sec:keyManagers keyPassword="${my.keystore.password}">
                    <sec:keyStore type="JKS"
                         password="${my.keystore.password}"
                         file="${my.keystore.file}" />
                  </sec:keyManagers>

                  <!-- Cipher suites filters specify the cipher suite to allow/disallow in SSL communcation  -->
                  <sec:cipherSuitesFilter>
                    <sec:include>.*_WITH_3DES_.*</sec:include>
                    <sec:include>.*_EXPORT_.*</sec:include>
                    <sec:include>.*_EXPORT1024_.*</sec:include
                    <sec:include>.*_WITH_DES_.*</sec:include
                    <sec:exclude>.*_WITH_NULL_.*</sec:exclude
                    <sec:exclude>.*_DH_anon_.*</sec:exclude>
                  </sec:cipherSuitesFilter>
    </http:tlsClientParameters>
</http:conduit>
</beans>

Java 客户端密码处理程序:

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.log4j.Logger;
import org.apache.ws.security.WSPasswordCallback;


/**
 * <p>
 * Provides a callback handler for use processing outbound/inbound SOAP messages.
 * ClientPasswordHandler sets the password used in the WS-Security UsernameToken 
 * SOAP header.
 * 
 * </p>
 * 
 * Created: Apr 1, 2009
 * @author Jared Knipp
 * 
 */
public final class ClientPasswordHandler implements CallbackHandler {
    protected static Logger log = Logger.getLogger(ClientPasswordHandler.class);

    private static final PropertyManager PROPS = PropertyManager.getInstance();
    private static String PASSWORD = PROPS.getPassword();
    private static boolean IS_PASSWORD_CLEAR = PROPS.getIsClearPassword();

    /**
     * Client password handler call back.  This method is used to provide
     * additional outbound (or could be inbound also) message processing.
     * 
     * Here the method sets the password used in the UsernameToken SOAP security header
     * element in the SOAP header of the outbound message.  For our purposes the clear 
     * text password is SHA1 hashed first before it is hashed again along with the nonce and 
     * current timestamp in the security header.
     */
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        if(log.isDebugEnabled()) { log.debug("Setting password for UsernameToken"); }
        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];


        // Check to see if the password is already Hashed via SHA1, if not then hash it first
        if(IS_PASSWORD_CLEAR) {
            synchronized(this) {
                PASSWORD = PasswordDigestUtil.doPasswordDigest(PASSWORD);
                IS_PASSWORD_CLEAR = false;
                PROPS.setIsClearPassword(IS_PASSWORD_CLEAR);
                PROPS.setPassword(PASSWORD);
                PROPS.saveProperties();
            }
        }

        pc.setPassword(PASSWORD);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAX-WS 通过 WS-Security 和 WS-Addressing 使用 Web 服务 的相关文章

  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • WCF 服务引用从 WSDL 生成 void 方法

    这是我第一次尝试使用 WCF 所以我猜我做错了什么 我正在尝试访问 WSDL 定义的肥皂服务http confluence atlassian com rpc soap axis confluenceservice v1 wsdl http
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 如何在桌面浏览器上使用 webdriver 移动网络

    我正在使用 selenium webdriver 进行 AUT 被测应用程序 的功能测试自动化 AUT 是响应式网络 我几乎完成了桌面浏览器的不同测试用例 现在 相同的测试用例也适用于移动浏览器 因为可以从移动浏览器访问 AUT 由于它是响

随机推荐

  • 淘汰 Twitter Bootstrap Popover 绑定

    我正在尝试为 twitter boostrap 弹出窗口创建一个引用模板的自定义绑定 但在创建弹出窗口后 我在处理弹出窗口内部内容的绑定部分时遇到了问题 我以前见过这个问题 但我觉得它们大多非常混乱 而且我非常接近一个可重用的解决方案 它可
  • sed + 如何通过 sed 获取“=”分隔符后的第二个单词(字符串)

    如何通过sed获取 分隔符后的第二个单词 字符串 需要忽略空格 例如 echo bla bla word word1 strin1 string2 sed 我应该得到 string2 另一个例子 echo bla bla word word
  • 我可以强制 jQuery.css("backgroundColor") 返回十六进制格式吗?

    我有一个这样的元素 p My text with a strong class highlighted sample highlight strong p p CSS 类是这样的 highlighted background f0ff05
  • 浮点倒数总是往返吗?

    对于 IEEE 754 算术 倒数的最后一位精度是否能保证 0 或 1 个单位 由此看来 倒数的倒数是否有保证的误差范围 下面的所有内容均假定固定的 IEEE 754 二进制格式 并采用某种形式的舍入到最接近的舍入模式 由于倒数 计算为1
  • git 的 Windows GUI [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我知道this问题 但现在有点旧了 有些答案似乎已经过时了 问题 请为每个 GUI 写一个答案你用过 包括优点和缺点 例如 据我所知 使用 git
  • HttpClient 的请求标头和内容标头有什么区别

    谁能解释一下请求标头和内容标头之间有什么区别 在这个特殊情况下 我谈论的是 UWPHttpClient目的 首先你创建HttpClient 然后你创建HttpRequestMessage然后你分配 就我而言HttpStreamContent
  • 在 Python 3 中处理文件内容时出现“TypeError: a bytes-like object is required, not 'str'”

    我最近迁移到 Python 3 5 这段代码在 Python 2 7 中可以正常工作 with open fname rb as f lines x strip for x in f readlines for line in lines
  • 如何从 Bash 数组中获取唯一值?

    我有几乎相同的问题here 我有一个数组 其中包含aa ab aa ac aa ad ETC 现在我想从此数组中选择所有唯一元素 我想 这会很简单sort uniq或与sort u正如他们在另一个问题中提到的那样 但数组中没有任何变化 代码
  • 当前端和后端位于虚拟 docker 网络中时,如何使用 axios 寻址后端主机

    我正在构建一个带有登录功能的简单网站 我的 vue 前端需要从连接到 sql 数据库的 Nodejs 后端检索用户数据 我决定为此使用 docker compose 据我了解 docker compose 会自动为 docker compo
  • 在 Java 2D 中实现 Polygon2D

    我正在使用 Java2D 绘图库在 Java 中创建一个 2D 游戏 我确实需要一个浮点精度的 Polygon 对象 我可以使用它来绘制游戏对象并对其进行碰撞检测 不幸的是 Java 的 Polygon 对象仅具有 int 精度 并且没有像
  • 是否有 Java“API”可以从 XSD 生成示例 XML?

    作为应用程序的一部分 我们需要开发一个模块 该模块接受 XSD 模式并给出示例 XML XSD 架构将在运行时提供 那么有没有 Java API 可以完成这项工作呢 搜索了一下这个论坛 发现了以下类似的问题 但讨论的重点是从 XSD 生成示
  • Vagrant ssh 身份验证失败

    ssh认证问题 gt default Clearing any previously set forwarded ports gt default Clearing any previously set network interfaces
  • 如何更改fabricjs中的旋转图标

    请指导我修改 Fabricjs 以添加自定义旋转图标 我得到了一些答案 但效果不佳 请让我知道仅更改特定旋转图标的代码 像这样更改织物对象原型 drawControls 这是一个例子JSFiddle fabric Object protot
  • 创建一个表,其中的列名源自另一个表的行值

    假设我有下表 其中只有一列 Table 1 nameCol A A B C 我想创建一个具有以下列名称的新表 Table 2 pk A B C 也就是说 一个表的数据成为第二个表的列名 在某种程度上可能涉及一个支点 但我无法真正得到答案 我
  • 核心数据查找或创建最有效的方法

    我有大约 10000 个实体对象 Message 当我添加一个新的 Message 我想首先查看它是否存在 如果存在 则仅更新其数据 但如果不存在 则创建它 现在 查找或创建 算法通过保存所有消息对象来工作 objectID 在一个数组中
  • 我如何进行自定义 Yii2 gridview 排序?

    如何进行自定义排序gridview header 请给出两者之间的区别label and header in the Yii2 gridview widget dataprovider 这是我的代码
  • PHP 中的字符串连接与数组内爆

    使用 Java 很长时间后 我逐段创建长字符串的标准方法是将元素添加到数组中 然后对数组进行内爆 out a out b echo implode out 但随后有大量数据 标准 PHP 替代方案是使用字符串连接 out a out b e
  • Python 装饰器处理文档字符串

    我在使用带有装饰器的文档字符串时遇到问题 给出以下示例 def decorator f def decorator print decorator active f return decorator decorator def foo th
  • RDD API 与 UDF 与 DataFrame API 混合的性能影响

    Scala 特定问题 虽然 Spark 文档鼓励尽可能使用 DataFrame API 但如果 DataFrame API 不足 通常需要选择回退到 RDD API 或使用 UDF 这两种替代方案之间是否存在固有的性能差异 RDD 和 UD
  • JAX-WS 通过 WS-Security 和 WS-Addressing 使用 Web 服务

    我正在尝试使用 JAX WS Metro 开发一个独立的 Java Web 服务客户端 该客户端使用 WS Security 和用户名令牌身份验证 密码摘要 随机数和时间戳 和时间戳验证以及基于 SSL 的 WS Addressing 我必