You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebLogic部署JAX-WS客户端遇UsernameToken安全令牌添加失败求助

JAX-WS调用WebService在WebLogic部署后仍报安全令牌错误问题

问题详情

调用WebService时收到如下SOAP错误响应:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>Unable to add security token for identity, token uri =http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</faultstring>
         <faultactor/>
      </S:Fault>
   </S:Body>
</S:Envelope>

针对该错误,我实现了自定义SOAP Handler来添加用户名密码凭证,本地Eclipse独立运行代码时一切正常,但部署到WebLogic客户端后仍抛出相同错误。日志中打印的SOAP信封复制到SoapUI调用却能正常工作。

自定义Handler代码

import java.util.Set;
import java.util.TreeSet;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;


public class UsrSecHandler implements SOAPHandler<SOAPMessageContext>
{
    private static final String AUTH_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
    private static final String AUTH_PREFIX="wsse";
    private String pwd;
    private String userName = null;
    private SOAPFactory mSoapFactory = null;
    


    public UsrSecHandler(String username, String password) {
        this.userName = username;
        this.pwd = password;
    }


    @Override
    public boolean handleMessage(SOAPMessageContext context)
    {

        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue())
        {

            try
            {
                
                SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
                if (mSoapFactory == null)
                {
                        mSoapFactory = SOAPFactory.newInstance();
                    
                }
                SOAPElement wsSecHeaderElm, userNameTokenElm, userNameElm, passwdElm;
                // WSSecurity <Security> header
                
                    wsSecHeaderElm = mSoapFactory.createElement("Security",AUTH_PREFIX,AUTH_NS);
                    userNameTokenElm = mSoapFactory.createElement("UsernameToken",AUTH_PREFIX,AUTH_NS);
                    userNameElm = mSoapFactory.createElement("Username",AUTH_PREFIX,AUTH_NS);
                    passwdElm = mSoapFactory.createElement("Password",AUTH_PREFIX,AUTH_NS);
                
                userNameElm.addTextNode(this.userName);
                passwdElm.addTextNode(this.pwd);

                userNameTokenElm.addChildElement(userNameElm);
                userNameTokenElm.addChildElement(passwdElm);
                
                // add child elements to the root element
                wsSecHeaderElm.addChildElement(userNameTokenElm);

                // create SOAPHeader instance for SOAP envelope             
                SOAPHeader header = envelope.getHeader();
                
                if (header == null) {
                    header = envelope.addHeader();
                }
                
                
                header.addChildElement(wsSecHeaderElm);
            }
            catch (SOAPException e)
            {
                    e.printStackTrace();
            }catch (Exception e){
                    e.printStackTrace();
            }
        }
        return true;
    }

    @Override
    public Set<QName> getHeaders()
    {
        return new TreeSet<QName>();
    }

    @Override
    public boolean handleFault(SOAPMessageContext context)
    {
        return false;
    }

    @Override
    public void close(MessageContext context)
    {
        //
    }
    
}

Handler配置与调用代码

ManagementServices  service = new ManagementServices(webServiceUrl);

Impl_ManagementServices port = service.getManagementServices();

final Binding binding = ((BindingProvider) port).getBinding();
 
List<Handler> handlerList = binding.getHandlerChain();

handlerList.add(new UsrSecHandler(LOGIN, PASS));

binding.setHandlerChain(handlerList);

port.callingManageService(some_input);

服务端安全策略

<wsp:Policy wssutil:Id="UsernameToken">
<ns1:SupportingTokens xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512">
<wsp:Policy>
<ns1:UsernameToken ns1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns1:WssUsernameToken10/>
</wsp:Policy>
</ns1:UsernameToken>
</wsp:Policy>
</ns1:SupportingTokens>
</wsp:Policy>

环境信息

  • 客户端WebLogic版本:14.1.1.0.0
  • 服务端WebLogic版本:10.3.6.0

解决方案建议

1. 避免WebLogic内置JAX-WS实现覆盖自定义逻辑

WebLogic 14c自带的WS-Security实现可能会修改自定义Handler添加的Security头,可通过weblogic.xml配置让应用优先使用自身的JAX-WS依赖:

<weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app">
    <wls:container-descriptor>
        <wls:prefer-application-packages>
            <wls:package-name>javax.xml.ws.*</wls:package-name>
            <wls:package-name>com.sun.xml.ws.*</wls:package-name>
            <wls:package-name>com.sun.xml.bind.*</wls:package-name>
        </wls:prefer-application-packages>
    </wls:container-descriptor>
</weblogic-web-app>

2. 调整Handler执行顺序

确保自定义Handler在WebLogic内置Handler之前执行,修改Handler添加逻辑:

// 插入到Handler链的第一个位置
handlerList.add(0, new UsrSecHandler(LOGIN, PASS));
binding.setHandlerChain(handlerList);

3. 完善UsernameToken的属性配置

服务端策略要求WssUsernameToken10,需补充必要的属性(比如wsu:Id和密码类型),修改Handler代码:

// 添加wsu命名空间定义
private static final String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
private static final String WSU_PREFIX = "wsu";

// 创建UsernameToken时添加Id属性
userNameTokenElm = mSoapFactory.createElement("UsernameToken", AUTH_PREFIX, AUTH_NS);
userNameTokenElm.addAttribute(new QName(WSU_NS, "Id", WSU_PREFIX), "UsernameToken-1");

// 给Password元素添加明文密码类型属性
passwdElm.addAttribute(new QName("Type"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");

4. 验证Handler是否实际执行

在handleMessage方法中添加日志输出,确认部署到WebLogic后Handler是否被调用:

System.out.println("Custom UsrSecHandler executed for outbound message");

如果未执行,可尝试通过weblogic-jaxws.xml配置文件注册Handler,而不是代码动态添加:

<weblogic-jaxws xmlns="http://xmlns.oracle.com/weblogic/weblogic-jaxws">
    <client>
        <port-info>
            <port-name>ManagementServicesPort</port-name>
            <handler-chain>
                <handler>
                    <handler-name>UsrSecHandler</handler-name>
                    <handler-class>com.yourpackage.UsrSecHandler</handler-class>
                    <init-param>
                        <param-name>username</param-name>
                        <param-value>your_login</param-value>
                    </init-param>
                    <init-param>
                        <param-name>password</param-name>
                        <param-value>your_pass</param-value>
                    </init-param>
                </handler>
            </handler-chain>
        </port-info>
    </client>
</weblogic-jaxws>

5. 检查WebLogic客户端安全配置冲突

确认WebLogic客户端是否配置了其他WS-Security策略(比如在weblogic-jaxws.xml或控制台中),这些配置可能会和自定义Handler冲突,暂时移除相关配置后再测试。


内容的提问来源于stack exchange,提问作者Atif Sheikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:28:11