我正在编写一个 SOAP 服务(我们称之为 X),它充当某种“转发代理”,替换正文中的几个元素,然后调用另一个 SOAP 服务 (Y)。我想使用调用 Y 时在 X 中收到的相同 WS-Security 凭据(纯文本用户名和密码),但是在检索 Password 元素的值时遇到了问题。
我在wsit-package.service.xml
文件中声明的策略引用了以下实现com.sun.xml.wss.impl.callback.PasswordValidationCallback.PasswordValidator
:
<wsp1_2:Policy wsu:Id="UsernameToken"
xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"
xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy">
<wsp1_2:ExactlyOne>
<wsp1_2:All>
<sp:SupportingTokens>
<wsp1_2:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/
ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient" />
<sp:IncludeTimestamp />
</wsp1_2:Policy>
</sp:SupportingTokens>
<wsss:ValidatorConfiguration wspp:visibility="private" >
<wsss:Validator name="usernameValidator"
classname="com.service.validator.SecurityValidator" />
</wsss:ValidatorConfiguration>
</wsp1_2:All>
</wsp1_2:ExactlyOne>
</wsp1_2:Policy>
我可以在验证器中访问密码:
@Override
public boolean validate(Request request) throws PasswordValidationException {
String password = ((PlainTextPasswordRequest) request).getPassword();
return true;
}
但是,由于验证器无权访问 WebServiceContext,因此我的服务端点无法方便地存储它。
使用其他标头,例如 WS-Addressing,我可以使用 Handler(的实现SOAPHandler<SOAPMessageContext>
)来提取值,然后将它们放回应用程序范围下的上下文中,以便我的端点检索。在 SOAP 消息到达我的处理程序链时,WS-Security 标头已经被剥离,因此无法在处理程序中检索它们的值。
没有做一些激烈的事情,比如使用验证器将密码存储在数据库/全局映射/线程本地存储中,我有什么方法可以检索在我的端点提供的 WS-Security 密码?
我应该注意,我可以通过 访问端点上的 WS-Security 用户名信息Subject subj = SubjectAccessor.getRequesterSubject(context)
,但这似乎不包含密码。