PasswordDigest authentication fails in JAX-WS client running in WebLogic












1















I'm trying to implement a JAX-WS web service client that uses PasswordDigest authentication.



This is my web service client:



import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.soap.AddressingFeature;

@Stateless
public class JaxWsService {

/**
* We cache the web service client, but on a thread local variable to avoid any potential multi-threading
* issues.
*/
private ThreadLocal<MyService> threadLocalClient = new ThreadLocal<MyService>();

@WebServiceRef(wsdlLocation = "http://localhost:9999/mockMyService?WSDL")
private MyServiceInterface service;

@PostConstruct
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<Handler>();
//Add a handler to the handler chain
handlerChain.add( new PasswordDigestHeaderHandler() );
Binding binding = ( ( BindingProvider )proxy ).getBinding();
binding.setHandlerChain(handlerChain);

threadLocalClient.set(proxy);
}

public Response doSomething(String guid) {
MyService client = threadLocalClient.get();
return client.doSomething(guid);
}
}


This is my SOAPHandler:



import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
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;

import ca.ns.gov.sns.rmv.util.PropertyUtil;
import sun.misc.BASE64Encoder;

public class PasswordDigestHeaderHandler implements SOAPHandler<SOAPMessageContext> {

private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static DateFormat headerDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
private static final String ENCODING_UTF_8 = "UTF-8";
private static final String wssePrefix = "wsse";
private static final String wsseURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String wsuPrefix = "wsu";
private static final String wsuURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";

@Override
public boolean handleMessage(SOAPMessageContext context) {

Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if (outboundProperty.booleanValue()) {
try {

// Nonce
SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
rand.setSeed(System.currentTimeMillis());
byte nonceBytes = new byte[16];
rand.nextBytes(nonceBytes);

// Created date
headerDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar now = Calendar.getInstance();
String createdDate = headerDateFormat.format(now.getTime());
byte createdDateBytes = createdDate.getBytes(ENCODING_UTF_8);

// Password
byte passwordBytes = PASSWORD.getBytes(ENCODING_UTF_8);

// SHA-1 hash the bunch of it.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(nonceBytes);
baos.write(createdDateBytes);
baos.write(passwordBytes);
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte digestedPassword = md.digest(baos.toByteArray());

// Encode the password and nonce
String passwordB64 = (new BASE64Encoder()).encode(digestedPassword);
String nonceB64 = (new BASE64Encoder()).encode(nonceBytes);

now.add(Calendar.SECOND, 1000);
String expiresTimestamp = headerDateFormat.format(now.getTime());

SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();

// Security
SOAPElement securityE = factory.createElement("Security", wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wsuPrefix, wsuURI);
securityE.addAttribute(new QName("mustUnderstand"), "1");

// Security/Timestamp
SOAPElement timestampE = factory.createElement("Timestamp", wsuPrefix, wsuURI);
timestampE.setAttributeNS(wsuURI, "wsu:Id", "TS-" + generateRandomString());

SOAPElement createdE = factory.createElement("Created", wsuPrefix, wsuURI);
createdE.addTextNode(createdDate);
timestampE.addChildElement(createdE);

SOAPElement expiresE = factory.createElement("Expires", wsuPrefix, wsuURI);
expiresE.addTextNode(expiresTimestamp);
timestampE.addChildElement(expiresE);

// Security/UsernameToken
SOAPElement usernameTokenE = factory.createElement("UsernameToken", wssePrefix, wsseURI);
usernameTokenE.setAttributeNS(wsuURI, "wsu:Id", "UsernameToken-" + generateRandomString());

SOAPElement userE = factory.createElement("Username", wssePrefix, wsseURI);
userE.addTextNode(USERNAME);

SOAPElement pwdE = factory.createElement("Password", wssePrefix, wsseURI);
pwdE.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
pwdE.addTextNode(passwordB64);

SOAPElement nonceE = factory.createElement("Nonce", wssePrefix, wsseURI);
nonceE.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceE.addTextNode(nonceB64);

usernameTokenE.addChildElement(userE);
usernameTokenE.addChildElement(pwdE);
usernameTokenE.addChildElement(nonceE);
usernameTokenE.addChildElement(createdE);

securityE.addChildElement(timestampE);
securityE.addChildElement(usernameTokenE);

SOAPHeader header = envelope.getHeader();

if (header == null){
header = envelope.addHeader();
}

header.addChildElement(securityE);

context.getMessage().saveChanges();
} catch (Exception e) {
e.printStackTrace();
}
}
return outboundProperty;
}

@Override
public Set<QName> getHeaders() {
QName securityHeader = new QName(wsseURI, "Security", wssePrefix);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}

@Override
public void close(MessageContext context) {}

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

/**
* Generates a random string used in the Timestamp and UsernameToken elements.
*
* @return
*/
private String generateRandomString() {
return UUID.randomUUID().toString().replaceAll("-", "");
}


... and these are my web service artifacts generate by ClientGenTask:



@WebServiceClient...
public class MyServiceInterface
extends Service
{


...



@WebService...
@XmlSeeAlso({
ObjectFactory.class
})
public interface MyService {


... and this is the web service's policy:



<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="wss_username_token_over_ssl_service_policy_PasswordDigest">
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false">
<wsp:Policy/>
</sp:HttpsToken>
</wsp:Policy>
</sp:TransportToken>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>


The bulk of the code is taken from a standalone application that I wrote as a proof of concept, which was working fine. I was able to hit the web service and get the expected response.



But when I migrated the code to run inside Weblogic 12.1.3, I started getting this error:




Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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




Is there some setup that needs to be done through the WebLogic console in order to enable PasswordDigest from the client side, or am I missing something in the code?



Here is the full stack trace:



Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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 Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:193)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:131)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:203)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:290)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:92)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:161)
at com.sun.proxy.$Proxy367.retrieveDocumentRequest(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:87)
at com.sun.proxy.$Proxy365.retrieveDocumentRequest(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService.retrieveDocument(MyServiceSOAJaxWsService.java:174)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy358.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:33)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyServiceBean.retrieveDocument(MyServiceBean.java:347)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy353.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.retrieveDocument(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:84)
at com.sun.proxy.$Proxy151.retrieveDocument(Unknown Source)
at com.myclient.project.web.ods.ODSRenderAttachment.init(ODSRenderAttachment.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokeAnnotatedMethod(WebContainerInjectionProvider.java:113)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokePostConstruct(WebContainerInjectionProvider.java:95)
at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:223)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:408)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:268)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:877)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1785)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.myclient.project.util.faces.CustomViewHandler.renderView(CustomViewHandler.java:63)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:604)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:54)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.PersistenceFilter.doFilter(PersistenceFilter.java:86)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.UploadFilter.doFilter(UploadFilter.java:83)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.ClientTransactionConversationFilter.doFilter(ClientTransactionConversationFilter.java:34)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)


Strangely, if I take the XML that's generated/output by the PasswordDigestHeaderHandler (below) and paste it into SoapUI, the request works. This seems to hint at some missing WebLogic configuration.



<S:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-6b8a287b7bf641f19b6841d555e9f380">
<wsu:Created>2018-11-13T18:11:53.541Z</wsu:Created>
<wsu:Expires>2018-11-13T18:28:33.541Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-183099de358f4f0685eb34783a8b1c5c">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">42Nl15QHYJymbpxFDFC5kccoWuk=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9NTLR/h+GQQwRd1fQRxnqg==</wsse:Nonce>
<wsu:Created
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-13T18:11:53.541Z
</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<S:Body>
<RetrieveDocumentRequest
xmlns="http://mycompany.com/MyService">
...
</RetrieveDocumentRequest>
</S:Body>
</S:Envelope>









share|improve this question

























  • Check the server side logs, they might give more insight. Also what's the WS-Policy look like for the WebLogic server?

    – xtratic
    Nov 13 '18 at 13:52











  • I've updated the question with the policy and the full stack trace. Unfortunately I don't have access to the server logs for the service I am trying to invoke.

    – freecouch
    Nov 13 '18 at 14:49











  • The stack trace only indicates that the server couldn't add a security token based on what it got. Client received SOAP Fault from server: 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

    – xtratic
    Nov 13 '18 at 19:46











  • I was wondering if there were namespace issues. But it looks and sounds like that's fine especially if you say the generated SOAP works when you send it via SoapUI. It does sound like a client environment issue then, I'm just trying to think what in the client environment would stop the server from being able to add the token.

    – xtratic
    Nov 13 '18 at 19:51











  • I've edited my answer, try it with the updates. Wondering if somehow the client not trusting the server is causing the issue? If not this then mess around more with the client environment.

    – xtratic
    Nov 13 '18 at 20:03
















1















I'm trying to implement a JAX-WS web service client that uses PasswordDigest authentication.



This is my web service client:



import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.soap.AddressingFeature;

@Stateless
public class JaxWsService {

/**
* We cache the web service client, but on a thread local variable to avoid any potential multi-threading
* issues.
*/
private ThreadLocal<MyService> threadLocalClient = new ThreadLocal<MyService>();

@WebServiceRef(wsdlLocation = "http://localhost:9999/mockMyService?WSDL")
private MyServiceInterface service;

@PostConstruct
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<Handler>();
//Add a handler to the handler chain
handlerChain.add( new PasswordDigestHeaderHandler() );
Binding binding = ( ( BindingProvider )proxy ).getBinding();
binding.setHandlerChain(handlerChain);

threadLocalClient.set(proxy);
}

public Response doSomething(String guid) {
MyService client = threadLocalClient.get();
return client.doSomething(guid);
}
}


This is my SOAPHandler:



import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
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;

import ca.ns.gov.sns.rmv.util.PropertyUtil;
import sun.misc.BASE64Encoder;

public class PasswordDigestHeaderHandler implements SOAPHandler<SOAPMessageContext> {

private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static DateFormat headerDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
private static final String ENCODING_UTF_8 = "UTF-8";
private static final String wssePrefix = "wsse";
private static final String wsseURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String wsuPrefix = "wsu";
private static final String wsuURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";

@Override
public boolean handleMessage(SOAPMessageContext context) {

Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if (outboundProperty.booleanValue()) {
try {

// Nonce
SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
rand.setSeed(System.currentTimeMillis());
byte nonceBytes = new byte[16];
rand.nextBytes(nonceBytes);

// Created date
headerDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar now = Calendar.getInstance();
String createdDate = headerDateFormat.format(now.getTime());
byte createdDateBytes = createdDate.getBytes(ENCODING_UTF_8);

// Password
byte passwordBytes = PASSWORD.getBytes(ENCODING_UTF_8);

// SHA-1 hash the bunch of it.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(nonceBytes);
baos.write(createdDateBytes);
baos.write(passwordBytes);
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte digestedPassword = md.digest(baos.toByteArray());

// Encode the password and nonce
String passwordB64 = (new BASE64Encoder()).encode(digestedPassword);
String nonceB64 = (new BASE64Encoder()).encode(nonceBytes);

now.add(Calendar.SECOND, 1000);
String expiresTimestamp = headerDateFormat.format(now.getTime());

SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();

// Security
SOAPElement securityE = factory.createElement("Security", wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wsuPrefix, wsuURI);
securityE.addAttribute(new QName("mustUnderstand"), "1");

// Security/Timestamp
SOAPElement timestampE = factory.createElement("Timestamp", wsuPrefix, wsuURI);
timestampE.setAttributeNS(wsuURI, "wsu:Id", "TS-" + generateRandomString());

SOAPElement createdE = factory.createElement("Created", wsuPrefix, wsuURI);
createdE.addTextNode(createdDate);
timestampE.addChildElement(createdE);

SOAPElement expiresE = factory.createElement("Expires", wsuPrefix, wsuURI);
expiresE.addTextNode(expiresTimestamp);
timestampE.addChildElement(expiresE);

// Security/UsernameToken
SOAPElement usernameTokenE = factory.createElement("UsernameToken", wssePrefix, wsseURI);
usernameTokenE.setAttributeNS(wsuURI, "wsu:Id", "UsernameToken-" + generateRandomString());

SOAPElement userE = factory.createElement("Username", wssePrefix, wsseURI);
userE.addTextNode(USERNAME);

SOAPElement pwdE = factory.createElement("Password", wssePrefix, wsseURI);
pwdE.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
pwdE.addTextNode(passwordB64);

SOAPElement nonceE = factory.createElement("Nonce", wssePrefix, wsseURI);
nonceE.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceE.addTextNode(nonceB64);

usernameTokenE.addChildElement(userE);
usernameTokenE.addChildElement(pwdE);
usernameTokenE.addChildElement(nonceE);
usernameTokenE.addChildElement(createdE);

securityE.addChildElement(timestampE);
securityE.addChildElement(usernameTokenE);

SOAPHeader header = envelope.getHeader();

if (header == null){
header = envelope.addHeader();
}

header.addChildElement(securityE);

context.getMessage().saveChanges();
} catch (Exception e) {
e.printStackTrace();
}
}
return outboundProperty;
}

@Override
public Set<QName> getHeaders() {
QName securityHeader = new QName(wsseURI, "Security", wssePrefix);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}

@Override
public void close(MessageContext context) {}

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

/**
* Generates a random string used in the Timestamp and UsernameToken elements.
*
* @return
*/
private String generateRandomString() {
return UUID.randomUUID().toString().replaceAll("-", "");
}


... and these are my web service artifacts generate by ClientGenTask:



@WebServiceClient...
public class MyServiceInterface
extends Service
{


...



@WebService...
@XmlSeeAlso({
ObjectFactory.class
})
public interface MyService {


... and this is the web service's policy:



<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="wss_username_token_over_ssl_service_policy_PasswordDigest">
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false">
<wsp:Policy/>
</sp:HttpsToken>
</wsp:Policy>
</sp:TransportToken>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>


The bulk of the code is taken from a standalone application that I wrote as a proof of concept, which was working fine. I was able to hit the web service and get the expected response.



But when I migrated the code to run inside Weblogic 12.1.3, I started getting this error:




Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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




Is there some setup that needs to be done through the WebLogic console in order to enable PasswordDigest from the client side, or am I missing something in the code?



Here is the full stack trace:



Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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 Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:193)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:131)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:203)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:290)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:92)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:161)
at com.sun.proxy.$Proxy367.retrieveDocumentRequest(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:87)
at com.sun.proxy.$Proxy365.retrieveDocumentRequest(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService.retrieveDocument(MyServiceSOAJaxWsService.java:174)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy358.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:33)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyServiceBean.retrieveDocument(MyServiceBean.java:347)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy353.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.retrieveDocument(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:84)
at com.sun.proxy.$Proxy151.retrieveDocument(Unknown Source)
at com.myclient.project.web.ods.ODSRenderAttachment.init(ODSRenderAttachment.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokeAnnotatedMethod(WebContainerInjectionProvider.java:113)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokePostConstruct(WebContainerInjectionProvider.java:95)
at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:223)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:408)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:268)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:877)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1785)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.myclient.project.util.faces.CustomViewHandler.renderView(CustomViewHandler.java:63)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:604)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:54)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.PersistenceFilter.doFilter(PersistenceFilter.java:86)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.UploadFilter.doFilter(UploadFilter.java:83)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.ClientTransactionConversationFilter.doFilter(ClientTransactionConversationFilter.java:34)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)


Strangely, if I take the XML that's generated/output by the PasswordDigestHeaderHandler (below) and paste it into SoapUI, the request works. This seems to hint at some missing WebLogic configuration.



<S:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-6b8a287b7bf641f19b6841d555e9f380">
<wsu:Created>2018-11-13T18:11:53.541Z</wsu:Created>
<wsu:Expires>2018-11-13T18:28:33.541Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-183099de358f4f0685eb34783a8b1c5c">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">42Nl15QHYJymbpxFDFC5kccoWuk=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9NTLR/h+GQQwRd1fQRxnqg==</wsse:Nonce>
<wsu:Created
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-13T18:11:53.541Z
</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<S:Body>
<RetrieveDocumentRequest
xmlns="http://mycompany.com/MyService">
...
</RetrieveDocumentRequest>
</S:Body>
</S:Envelope>









share|improve this question

























  • Check the server side logs, they might give more insight. Also what's the WS-Policy look like for the WebLogic server?

    – xtratic
    Nov 13 '18 at 13:52











  • I've updated the question with the policy and the full stack trace. Unfortunately I don't have access to the server logs for the service I am trying to invoke.

    – freecouch
    Nov 13 '18 at 14:49











  • The stack trace only indicates that the server couldn't add a security token based on what it got. Client received SOAP Fault from server: 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

    – xtratic
    Nov 13 '18 at 19:46











  • I was wondering if there were namespace issues. But it looks and sounds like that's fine especially if you say the generated SOAP works when you send it via SoapUI. It does sound like a client environment issue then, I'm just trying to think what in the client environment would stop the server from being able to add the token.

    – xtratic
    Nov 13 '18 at 19:51











  • I've edited my answer, try it with the updates. Wondering if somehow the client not trusting the server is causing the issue? If not this then mess around more with the client environment.

    – xtratic
    Nov 13 '18 at 20:03














1












1








1








I'm trying to implement a JAX-WS web service client that uses PasswordDigest authentication.



This is my web service client:



import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.soap.AddressingFeature;

@Stateless
public class JaxWsService {

/**
* We cache the web service client, but on a thread local variable to avoid any potential multi-threading
* issues.
*/
private ThreadLocal<MyService> threadLocalClient = new ThreadLocal<MyService>();

@WebServiceRef(wsdlLocation = "http://localhost:9999/mockMyService?WSDL")
private MyServiceInterface service;

@PostConstruct
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<Handler>();
//Add a handler to the handler chain
handlerChain.add( new PasswordDigestHeaderHandler() );
Binding binding = ( ( BindingProvider )proxy ).getBinding();
binding.setHandlerChain(handlerChain);

threadLocalClient.set(proxy);
}

public Response doSomething(String guid) {
MyService client = threadLocalClient.get();
return client.doSomething(guid);
}
}


This is my SOAPHandler:



import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
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;

import ca.ns.gov.sns.rmv.util.PropertyUtil;
import sun.misc.BASE64Encoder;

public class PasswordDigestHeaderHandler implements SOAPHandler<SOAPMessageContext> {

private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static DateFormat headerDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
private static final String ENCODING_UTF_8 = "UTF-8";
private static final String wssePrefix = "wsse";
private static final String wsseURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String wsuPrefix = "wsu";
private static final String wsuURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";

@Override
public boolean handleMessage(SOAPMessageContext context) {

Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if (outboundProperty.booleanValue()) {
try {

// Nonce
SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
rand.setSeed(System.currentTimeMillis());
byte nonceBytes = new byte[16];
rand.nextBytes(nonceBytes);

// Created date
headerDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar now = Calendar.getInstance();
String createdDate = headerDateFormat.format(now.getTime());
byte createdDateBytes = createdDate.getBytes(ENCODING_UTF_8);

// Password
byte passwordBytes = PASSWORD.getBytes(ENCODING_UTF_8);

// SHA-1 hash the bunch of it.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(nonceBytes);
baos.write(createdDateBytes);
baos.write(passwordBytes);
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte digestedPassword = md.digest(baos.toByteArray());

// Encode the password and nonce
String passwordB64 = (new BASE64Encoder()).encode(digestedPassword);
String nonceB64 = (new BASE64Encoder()).encode(nonceBytes);

now.add(Calendar.SECOND, 1000);
String expiresTimestamp = headerDateFormat.format(now.getTime());

SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();

// Security
SOAPElement securityE = factory.createElement("Security", wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wsuPrefix, wsuURI);
securityE.addAttribute(new QName("mustUnderstand"), "1");

// Security/Timestamp
SOAPElement timestampE = factory.createElement("Timestamp", wsuPrefix, wsuURI);
timestampE.setAttributeNS(wsuURI, "wsu:Id", "TS-" + generateRandomString());

SOAPElement createdE = factory.createElement("Created", wsuPrefix, wsuURI);
createdE.addTextNode(createdDate);
timestampE.addChildElement(createdE);

SOAPElement expiresE = factory.createElement("Expires", wsuPrefix, wsuURI);
expiresE.addTextNode(expiresTimestamp);
timestampE.addChildElement(expiresE);

// Security/UsernameToken
SOAPElement usernameTokenE = factory.createElement("UsernameToken", wssePrefix, wsseURI);
usernameTokenE.setAttributeNS(wsuURI, "wsu:Id", "UsernameToken-" + generateRandomString());

SOAPElement userE = factory.createElement("Username", wssePrefix, wsseURI);
userE.addTextNode(USERNAME);

SOAPElement pwdE = factory.createElement("Password", wssePrefix, wsseURI);
pwdE.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
pwdE.addTextNode(passwordB64);

SOAPElement nonceE = factory.createElement("Nonce", wssePrefix, wsseURI);
nonceE.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceE.addTextNode(nonceB64);

usernameTokenE.addChildElement(userE);
usernameTokenE.addChildElement(pwdE);
usernameTokenE.addChildElement(nonceE);
usernameTokenE.addChildElement(createdE);

securityE.addChildElement(timestampE);
securityE.addChildElement(usernameTokenE);

SOAPHeader header = envelope.getHeader();

if (header == null){
header = envelope.addHeader();
}

header.addChildElement(securityE);

context.getMessage().saveChanges();
} catch (Exception e) {
e.printStackTrace();
}
}
return outboundProperty;
}

@Override
public Set<QName> getHeaders() {
QName securityHeader = new QName(wsseURI, "Security", wssePrefix);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}

@Override
public void close(MessageContext context) {}

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

/**
* Generates a random string used in the Timestamp and UsernameToken elements.
*
* @return
*/
private String generateRandomString() {
return UUID.randomUUID().toString().replaceAll("-", "");
}


... and these are my web service artifacts generate by ClientGenTask:



@WebServiceClient...
public class MyServiceInterface
extends Service
{


...



@WebService...
@XmlSeeAlso({
ObjectFactory.class
})
public interface MyService {


... and this is the web service's policy:



<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="wss_username_token_over_ssl_service_policy_PasswordDigest">
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false">
<wsp:Policy/>
</sp:HttpsToken>
</wsp:Policy>
</sp:TransportToken>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>


The bulk of the code is taken from a standalone application that I wrote as a proof of concept, which was working fine. I was able to hit the web service and get the expected response.



But when I migrated the code to run inside Weblogic 12.1.3, I started getting this error:




Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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




Is there some setup that needs to be done through the WebLogic console in order to enable PasswordDigest from the client side, or am I missing something in the code?



Here is the full stack trace:



Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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 Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:193)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:131)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:203)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:290)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:92)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:161)
at com.sun.proxy.$Proxy367.retrieveDocumentRequest(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:87)
at com.sun.proxy.$Proxy365.retrieveDocumentRequest(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService.retrieveDocument(MyServiceSOAJaxWsService.java:174)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy358.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:33)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyServiceBean.retrieveDocument(MyServiceBean.java:347)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy353.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.retrieveDocument(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:84)
at com.sun.proxy.$Proxy151.retrieveDocument(Unknown Source)
at com.myclient.project.web.ods.ODSRenderAttachment.init(ODSRenderAttachment.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokeAnnotatedMethod(WebContainerInjectionProvider.java:113)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokePostConstruct(WebContainerInjectionProvider.java:95)
at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:223)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:408)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:268)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:877)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1785)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.myclient.project.util.faces.CustomViewHandler.renderView(CustomViewHandler.java:63)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:604)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:54)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.PersistenceFilter.doFilter(PersistenceFilter.java:86)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.UploadFilter.doFilter(UploadFilter.java:83)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.ClientTransactionConversationFilter.doFilter(ClientTransactionConversationFilter.java:34)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)


Strangely, if I take the XML that's generated/output by the PasswordDigestHeaderHandler (below) and paste it into SoapUI, the request works. This seems to hint at some missing WebLogic configuration.



<S:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-6b8a287b7bf641f19b6841d555e9f380">
<wsu:Created>2018-11-13T18:11:53.541Z</wsu:Created>
<wsu:Expires>2018-11-13T18:28:33.541Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-183099de358f4f0685eb34783a8b1c5c">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">42Nl15QHYJymbpxFDFC5kccoWuk=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9NTLR/h+GQQwRd1fQRxnqg==</wsse:Nonce>
<wsu:Created
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-13T18:11:53.541Z
</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<S:Body>
<RetrieveDocumentRequest
xmlns="http://mycompany.com/MyService">
...
</RetrieveDocumentRequest>
</S:Body>
</S:Envelope>









share|improve this question
















I'm trying to implement a JAX-WS web service client that uses PasswordDigest authentication.



This is my web service client:



import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.soap.AddressingFeature;

@Stateless
public class JaxWsService {

/**
* We cache the web service client, but on a thread local variable to avoid any potential multi-threading
* issues.
*/
private ThreadLocal<MyService> threadLocalClient = new ThreadLocal<MyService>();

@WebServiceRef(wsdlLocation = "http://localhost:9999/mockMyService?WSDL")
private MyServiceInterface service;

@PostConstruct
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<Handler>();
//Add a handler to the handler chain
handlerChain.add( new PasswordDigestHeaderHandler() );
Binding binding = ( ( BindingProvider )proxy ).getBinding();
binding.setHandlerChain(handlerChain);

threadLocalClient.set(proxy);
}

public Response doSomething(String guid) {
MyService client = threadLocalClient.get();
return client.doSomething(guid);
}
}


This is my SOAPHandler:



import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
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;

import ca.ns.gov.sns.rmv.util.PropertyUtil;
import sun.misc.BASE64Encoder;

public class PasswordDigestHeaderHandler implements SOAPHandler<SOAPMessageContext> {

private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static DateFormat headerDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
private static final String ENCODING_UTF_8 = "UTF-8";
private static final String wssePrefix = "wsse";
private static final String wsseURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String wsuPrefix = "wsu";
private static final String wsuURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";

@Override
public boolean handleMessage(SOAPMessageContext context) {

Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if (outboundProperty.booleanValue()) {
try {

// Nonce
SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
rand.setSeed(System.currentTimeMillis());
byte nonceBytes = new byte[16];
rand.nextBytes(nonceBytes);

// Created date
headerDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar now = Calendar.getInstance();
String createdDate = headerDateFormat.format(now.getTime());
byte createdDateBytes = createdDate.getBytes(ENCODING_UTF_8);

// Password
byte passwordBytes = PASSWORD.getBytes(ENCODING_UTF_8);

// SHA-1 hash the bunch of it.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(nonceBytes);
baos.write(createdDateBytes);
baos.write(passwordBytes);
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte digestedPassword = md.digest(baos.toByteArray());

// Encode the password and nonce
String passwordB64 = (new BASE64Encoder()).encode(digestedPassword);
String nonceB64 = (new BASE64Encoder()).encode(nonceBytes);

now.add(Calendar.SECOND, 1000);
String expiresTimestamp = headerDateFormat.format(now.getTime());

SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();

// Security
SOAPElement securityE = factory.createElement("Security", wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wsuPrefix, wsuURI);
securityE.addAttribute(new QName("mustUnderstand"), "1");

// Security/Timestamp
SOAPElement timestampE = factory.createElement("Timestamp", wsuPrefix, wsuURI);
timestampE.setAttributeNS(wsuURI, "wsu:Id", "TS-" + generateRandomString());

SOAPElement createdE = factory.createElement("Created", wsuPrefix, wsuURI);
createdE.addTextNode(createdDate);
timestampE.addChildElement(createdE);

SOAPElement expiresE = factory.createElement("Expires", wsuPrefix, wsuURI);
expiresE.addTextNode(expiresTimestamp);
timestampE.addChildElement(expiresE);

// Security/UsernameToken
SOAPElement usernameTokenE = factory.createElement("UsernameToken", wssePrefix, wsseURI);
usernameTokenE.setAttributeNS(wsuURI, "wsu:Id", "UsernameToken-" + generateRandomString());

SOAPElement userE = factory.createElement("Username", wssePrefix, wsseURI);
userE.addTextNode(USERNAME);

SOAPElement pwdE = factory.createElement("Password", wssePrefix, wsseURI);
pwdE.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
pwdE.addTextNode(passwordB64);

SOAPElement nonceE = factory.createElement("Nonce", wssePrefix, wsseURI);
nonceE.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceE.addTextNode(nonceB64);

usernameTokenE.addChildElement(userE);
usernameTokenE.addChildElement(pwdE);
usernameTokenE.addChildElement(nonceE);
usernameTokenE.addChildElement(createdE);

securityE.addChildElement(timestampE);
securityE.addChildElement(usernameTokenE);

SOAPHeader header = envelope.getHeader();

if (header == null){
header = envelope.addHeader();
}

header.addChildElement(securityE);

context.getMessage().saveChanges();
} catch (Exception e) {
e.printStackTrace();
}
}
return outboundProperty;
}

@Override
public Set<QName> getHeaders() {
QName securityHeader = new QName(wsseURI, "Security", wssePrefix);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}

@Override
public void close(MessageContext context) {}

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

/**
* Generates a random string used in the Timestamp and UsernameToken elements.
*
* @return
*/
private String generateRandomString() {
return UUID.randomUUID().toString().replaceAll("-", "");
}


... and these are my web service artifacts generate by ClientGenTask:



@WebServiceClient...
public class MyServiceInterface
extends Service
{


...



@WebService...
@XmlSeeAlso({
ObjectFactory.class
})
public interface MyService {


... and this is the web service's policy:



<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="wss_username_token_over_ssl_service_policy_PasswordDigest">
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false">
<wsp:Policy/>
</sp:HttpsToken>
</wsp:Policy>
</sp:TransportToken>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>


The bulk of the code is taken from a standalone application that I wrote as a proof of concept, which was working fine. I was able to hit the web service and get the expected response.



But when I migrated the code to run inside Weblogic 12.1.3, I started getting this error:




Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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




Is there some setup that needs to be done through the WebLogic console in order to enable PasswordDigest from the client side, or am I missing something in the code?



Here is the full stack trace:



Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: 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 Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:193)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:131)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:203)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:290)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:92)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:161)
at com.sun.proxy.$Proxy367.retrieveDocumentRequest(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:87)
at com.sun.proxy.$Proxy365.retrieveDocumentRequest(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService.retrieveDocument(MyServiceSOAJaxWsService.java:174)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy358.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:33)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyServiceBean.retrieveDocument(MyServiceBean.java:347)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy353.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.retrieveDocument(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:84)
at com.sun.proxy.$Proxy151.retrieveDocument(Unknown Source)
at com.myclient.project.web.ods.ODSRenderAttachment.init(ODSRenderAttachment.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokeAnnotatedMethod(WebContainerInjectionProvider.java:113)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokePostConstruct(WebContainerInjectionProvider.java:95)
at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:223)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:408)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:268)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:877)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1785)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.myclient.project.util.faces.CustomViewHandler.renderView(CustomViewHandler.java:63)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:604)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:54)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.PersistenceFilter.doFilter(PersistenceFilter.java:86)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.UploadFilter.doFilter(UploadFilter.java:83)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.ClientTransactionConversationFilter.doFilter(ClientTransactionConversationFilter.java:34)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)


Strangely, if I take the XML that's generated/output by the PasswordDigestHeaderHandler (below) and paste it into SoapUI, the request works. This seems to hint at some missing WebLogic configuration.



<S:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-6b8a287b7bf641f19b6841d555e9f380">
<wsu:Created>2018-11-13T18:11:53.541Z</wsu:Created>
<wsu:Expires>2018-11-13T18:28:33.541Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-183099de358f4f0685eb34783a8b1c5c">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">42Nl15QHYJymbpxFDFC5kccoWuk=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9NTLR/h+GQQwRd1fQRxnqg==</wsse:Nonce>
<wsu:Created
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-13T18:11:53.541Z
</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<S:Body>
<RetrieveDocumentRequest
xmlns="http://mycompany.com/MyService">
...
</RetrieveDocumentRequest>
</S:Body>
</S:Envelope>






java jax-ws soap-client weblogic12c






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 18:33







freecouch

















asked Nov 13 '18 at 13:16









freecouchfreecouch

154415




154415













  • Check the server side logs, they might give more insight. Also what's the WS-Policy look like for the WebLogic server?

    – xtratic
    Nov 13 '18 at 13:52











  • I've updated the question with the policy and the full stack trace. Unfortunately I don't have access to the server logs for the service I am trying to invoke.

    – freecouch
    Nov 13 '18 at 14:49











  • The stack trace only indicates that the server couldn't add a security token based on what it got. Client received SOAP Fault from server: 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

    – xtratic
    Nov 13 '18 at 19:46











  • I was wondering if there were namespace issues. But it looks and sounds like that's fine especially if you say the generated SOAP works when you send it via SoapUI. It does sound like a client environment issue then, I'm just trying to think what in the client environment would stop the server from being able to add the token.

    – xtratic
    Nov 13 '18 at 19:51











  • I've edited my answer, try it with the updates. Wondering if somehow the client not trusting the server is causing the issue? If not this then mess around more with the client environment.

    – xtratic
    Nov 13 '18 at 20:03



















  • Check the server side logs, they might give more insight. Also what's the WS-Policy look like for the WebLogic server?

    – xtratic
    Nov 13 '18 at 13:52











  • I've updated the question with the policy and the full stack trace. Unfortunately I don't have access to the server logs for the service I am trying to invoke.

    – freecouch
    Nov 13 '18 at 14:49











  • The stack trace only indicates that the server couldn't add a security token based on what it got. Client received SOAP Fault from server: 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

    – xtratic
    Nov 13 '18 at 19:46











  • I was wondering if there were namespace issues. But it looks and sounds like that's fine especially if you say the generated SOAP works when you send it via SoapUI. It does sound like a client environment issue then, I'm just trying to think what in the client environment would stop the server from being able to add the token.

    – xtratic
    Nov 13 '18 at 19:51











  • I've edited my answer, try it with the updates. Wondering if somehow the client not trusting the server is causing the issue? If not this then mess around more with the client environment.

    – xtratic
    Nov 13 '18 at 20:03

















Check the server side logs, they might give more insight. Also what's the WS-Policy look like for the WebLogic server?

– xtratic
Nov 13 '18 at 13:52





Check the server side logs, they might give more insight. Also what's the WS-Policy look like for the WebLogic server?

– xtratic
Nov 13 '18 at 13:52













I've updated the question with the policy and the full stack trace. Unfortunately I don't have access to the server logs for the service I am trying to invoke.

– freecouch
Nov 13 '18 at 14:49





I've updated the question with the policy and the full stack trace. Unfortunately I don't have access to the server logs for the service I am trying to invoke.

– freecouch
Nov 13 '18 at 14:49













The stack trace only indicates that the server couldn't add a security token based on what it got. Client received SOAP Fault from server: 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

– xtratic
Nov 13 '18 at 19:46





The stack trace only indicates that the server couldn't add a security token based on what it got. Client received SOAP Fault from server: 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

– xtratic
Nov 13 '18 at 19:46













I was wondering if there were namespace issues. But it looks and sounds like that's fine especially if you say the generated SOAP works when you send it via SoapUI. It does sound like a client environment issue then, I'm just trying to think what in the client environment would stop the server from being able to add the token.

– xtratic
Nov 13 '18 at 19:51





I was wondering if there were namespace issues. But it looks and sounds like that's fine especially if you say the generated SOAP works when you send it via SoapUI. It does sound like a client environment issue then, I'm just trying to think what in the client environment would stop the server from being able to add the token.

– xtratic
Nov 13 '18 at 19:51













I've edited my answer, try it with the updates. Wondering if somehow the client not trusting the server is causing the issue? If not this then mess around more with the client environment.

– xtratic
Nov 13 '18 at 20:03





I've edited my answer, try it with the updates. Wondering if somehow the client not trusting the server is causing the issue? If not this then mess around more with the client environment.

– xtratic
Nov 13 '18 at 20:03












2 Answers
2






active

oldest

votes


















1














Try this.




  1. Download the WSDL file that describes your service and modify it by commenting out line that defines the wsp:PolicyReference:.


enter image description here




  1. Place it in a folder which will be included in your jar/war/ear file (eg. META-INF/wsdl).



  2. In your web service client, change your @WebServiceRef injection to reference this local/bundled version of the WSDL:



    @WebServiceRef(wsdlLocation = "META-INF/wsdl/MyService.wsdl")
    private MyServiceInterface service;



  3. Modify your client initialization code to something like the following:



    AddressingFeature feature = new AddressingFeature(true, false);
    MyService proxy = service.getMyService(feature);
    BindingProvider bindingProvider = (BindingProvider) proxy;

    List<Handler> handlerChain = new ArrayList<Handler>();
    //Add a handler to the handler chain
    handlerChain.add( new PasswordDigestHeaderHandler() );
    Binding binding = bindingProvider.getBinding();
    binding.setHandlerChain(handlerChain);

    // Add these two lines, to point to the remote service
    Map<String, Object> context = bindingProvider.getRequestContext();
    context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, REMOTE_SERVICE_ENDPOINT);

    threadLocalClient.set(proxy);



... where REMOTE_SERVICE_ENDPOINT is the URL to the remote web service that you are hitting.



That should do it. You shouldn't have to modify your PasswordDigestHeaderHandler implementation.



I spent a considerable amount of time on exactly this same issue, but this thread set me down the right path: https://community.oracle.com/thread/2485783.



Good luck.






share|improve this answer


























  • This worked! Thanks!

    – freecouch
    Nov 20 '18 at 13:21



















0














Try this for your init() method, you may need to add a WebLogic credential provider:



private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<>();
// Add a handler to the handler chain
handlerChain.add(new PasswordDigestHeaderHandler());

BindingProvider bindingProvider = (BindingProvider) proxy;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);

// weblogic.xml.crypto.wss.provider.CredentialProvider
// weblogic.wsee.security.unt.ClientUNTCredentialProvider
List<CredentialProvider> credProviders = new ArrayList<>();
credProviders.add(new ClientUNTCredentialProvider(USERNAME.getBytes(), PASSWORD.getBytes()));

Map<String, Object> context = bindingProvider.getRequestContext();
// weblogic.xml.crypto.wss.WSSecurityContext
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
// weblogic.security.SSL.TrustManager
context.put(
WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate chain, int validateErr) {
return true;
}
}
);

threadLocalClient.set(proxy);
}





share|improve this answer


























  • I tried that approach and I get the following error: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. I also have to comment out the handler chain code, otherwise I end up with two UsernameToken and two Timestamp elements. Also this approach does not encrypt the password, it creates a PasswordText password.

    – freecouch
    Nov 13 '18 at 18:12













  • Hmm, which approach gets further, does Timestamp validation or adding a Security Token come later in the server's processing? Probably the latter. Do you have something printing out your client request so you/we can check it? If logs aren't doing that for you then you can use <SOAPMessage>.writeTo(OutputStream)

    – xtratic
    Nov 13 '18 at 18:25











  • I added the generated XML and an additional comment to the original question.

    – freecouch
    Nov 13 '18 at 18:34











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53281854%2fpassworddigest-authentication-fails-in-jax-ws-client-running-in-weblogic%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Try this.




  1. Download the WSDL file that describes your service and modify it by commenting out line that defines the wsp:PolicyReference:.


enter image description here




  1. Place it in a folder which will be included in your jar/war/ear file (eg. META-INF/wsdl).



  2. In your web service client, change your @WebServiceRef injection to reference this local/bundled version of the WSDL:



    @WebServiceRef(wsdlLocation = "META-INF/wsdl/MyService.wsdl")
    private MyServiceInterface service;



  3. Modify your client initialization code to something like the following:



    AddressingFeature feature = new AddressingFeature(true, false);
    MyService proxy = service.getMyService(feature);
    BindingProvider bindingProvider = (BindingProvider) proxy;

    List<Handler> handlerChain = new ArrayList<Handler>();
    //Add a handler to the handler chain
    handlerChain.add( new PasswordDigestHeaderHandler() );
    Binding binding = bindingProvider.getBinding();
    binding.setHandlerChain(handlerChain);

    // Add these two lines, to point to the remote service
    Map<String, Object> context = bindingProvider.getRequestContext();
    context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, REMOTE_SERVICE_ENDPOINT);

    threadLocalClient.set(proxy);



... where REMOTE_SERVICE_ENDPOINT is the URL to the remote web service that you are hitting.



That should do it. You shouldn't have to modify your PasswordDigestHeaderHandler implementation.



I spent a considerable amount of time on exactly this same issue, but this thread set me down the right path: https://community.oracle.com/thread/2485783.



Good luck.






share|improve this answer


























  • This worked! Thanks!

    – freecouch
    Nov 20 '18 at 13:21
















1














Try this.




  1. Download the WSDL file that describes your service and modify it by commenting out line that defines the wsp:PolicyReference:.


enter image description here




  1. Place it in a folder which will be included in your jar/war/ear file (eg. META-INF/wsdl).



  2. In your web service client, change your @WebServiceRef injection to reference this local/bundled version of the WSDL:



    @WebServiceRef(wsdlLocation = "META-INF/wsdl/MyService.wsdl")
    private MyServiceInterface service;



  3. Modify your client initialization code to something like the following:



    AddressingFeature feature = new AddressingFeature(true, false);
    MyService proxy = service.getMyService(feature);
    BindingProvider bindingProvider = (BindingProvider) proxy;

    List<Handler> handlerChain = new ArrayList<Handler>();
    //Add a handler to the handler chain
    handlerChain.add( new PasswordDigestHeaderHandler() );
    Binding binding = bindingProvider.getBinding();
    binding.setHandlerChain(handlerChain);

    // Add these two lines, to point to the remote service
    Map<String, Object> context = bindingProvider.getRequestContext();
    context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, REMOTE_SERVICE_ENDPOINT);

    threadLocalClient.set(proxy);



... where REMOTE_SERVICE_ENDPOINT is the URL to the remote web service that you are hitting.



That should do it. You shouldn't have to modify your PasswordDigestHeaderHandler implementation.



I spent a considerable amount of time on exactly this same issue, but this thread set me down the right path: https://community.oracle.com/thread/2485783.



Good luck.






share|improve this answer


























  • This worked! Thanks!

    – freecouch
    Nov 20 '18 at 13:21














1












1








1







Try this.




  1. Download the WSDL file that describes your service and modify it by commenting out line that defines the wsp:PolicyReference:.


enter image description here




  1. Place it in a folder which will be included in your jar/war/ear file (eg. META-INF/wsdl).



  2. In your web service client, change your @WebServiceRef injection to reference this local/bundled version of the WSDL:



    @WebServiceRef(wsdlLocation = "META-INF/wsdl/MyService.wsdl")
    private MyServiceInterface service;



  3. Modify your client initialization code to something like the following:



    AddressingFeature feature = new AddressingFeature(true, false);
    MyService proxy = service.getMyService(feature);
    BindingProvider bindingProvider = (BindingProvider) proxy;

    List<Handler> handlerChain = new ArrayList<Handler>();
    //Add a handler to the handler chain
    handlerChain.add( new PasswordDigestHeaderHandler() );
    Binding binding = bindingProvider.getBinding();
    binding.setHandlerChain(handlerChain);

    // Add these two lines, to point to the remote service
    Map<String, Object> context = bindingProvider.getRequestContext();
    context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, REMOTE_SERVICE_ENDPOINT);

    threadLocalClient.set(proxy);



... where REMOTE_SERVICE_ENDPOINT is the URL to the remote web service that you are hitting.



That should do it. You shouldn't have to modify your PasswordDigestHeaderHandler implementation.



I spent a considerable amount of time on exactly this same issue, but this thread set me down the right path: https://community.oracle.com/thread/2485783.



Good luck.






share|improve this answer















Try this.




  1. Download the WSDL file that describes your service and modify it by commenting out line that defines the wsp:PolicyReference:.


enter image description here




  1. Place it in a folder which will be included in your jar/war/ear file (eg. META-INF/wsdl).



  2. In your web service client, change your @WebServiceRef injection to reference this local/bundled version of the WSDL:



    @WebServiceRef(wsdlLocation = "META-INF/wsdl/MyService.wsdl")
    private MyServiceInterface service;



  3. Modify your client initialization code to something like the following:



    AddressingFeature feature = new AddressingFeature(true, false);
    MyService proxy = service.getMyService(feature);
    BindingProvider bindingProvider = (BindingProvider) proxy;

    List<Handler> handlerChain = new ArrayList<Handler>();
    //Add a handler to the handler chain
    handlerChain.add( new PasswordDigestHeaderHandler() );
    Binding binding = bindingProvider.getBinding();
    binding.setHandlerChain(handlerChain);

    // Add these two lines, to point to the remote service
    Map<String, Object> context = bindingProvider.getRequestContext();
    context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, REMOTE_SERVICE_ENDPOINT);

    threadLocalClient.set(proxy);



... where REMOTE_SERVICE_ENDPOINT is the URL to the remote web service that you are hitting.



That should do it. You shouldn't have to modify your PasswordDigestHeaderHandler implementation.



I spent a considerable amount of time on exactly this same issue, but this thread set me down the right path: https://community.oracle.com/thread/2485783.



Good luck.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 17 '18 at 1:42

























answered Nov 17 '18 at 1:34









60066046006604

5,80411523




5,80411523













  • This worked! Thanks!

    – freecouch
    Nov 20 '18 at 13:21



















  • This worked! Thanks!

    – freecouch
    Nov 20 '18 at 13:21

















This worked! Thanks!

– freecouch
Nov 20 '18 at 13:21





This worked! Thanks!

– freecouch
Nov 20 '18 at 13:21













0














Try this for your init() method, you may need to add a WebLogic credential provider:



private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<>();
// Add a handler to the handler chain
handlerChain.add(new PasswordDigestHeaderHandler());

BindingProvider bindingProvider = (BindingProvider) proxy;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);

// weblogic.xml.crypto.wss.provider.CredentialProvider
// weblogic.wsee.security.unt.ClientUNTCredentialProvider
List<CredentialProvider> credProviders = new ArrayList<>();
credProviders.add(new ClientUNTCredentialProvider(USERNAME.getBytes(), PASSWORD.getBytes()));

Map<String, Object> context = bindingProvider.getRequestContext();
// weblogic.xml.crypto.wss.WSSecurityContext
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
// weblogic.security.SSL.TrustManager
context.put(
WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate chain, int validateErr) {
return true;
}
}
);

threadLocalClient.set(proxy);
}





share|improve this answer


























  • I tried that approach and I get the following error: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. I also have to comment out the handler chain code, otherwise I end up with two UsernameToken and two Timestamp elements. Also this approach does not encrypt the password, it creates a PasswordText password.

    – freecouch
    Nov 13 '18 at 18:12













  • Hmm, which approach gets further, does Timestamp validation or adding a Security Token come later in the server's processing? Probably the latter. Do you have something printing out your client request so you/we can check it? If logs aren't doing that for you then you can use <SOAPMessage>.writeTo(OutputStream)

    – xtratic
    Nov 13 '18 at 18:25











  • I added the generated XML and an additional comment to the original question.

    – freecouch
    Nov 13 '18 at 18:34
















0














Try this for your init() method, you may need to add a WebLogic credential provider:



private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<>();
// Add a handler to the handler chain
handlerChain.add(new PasswordDigestHeaderHandler());

BindingProvider bindingProvider = (BindingProvider) proxy;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);

// weblogic.xml.crypto.wss.provider.CredentialProvider
// weblogic.wsee.security.unt.ClientUNTCredentialProvider
List<CredentialProvider> credProviders = new ArrayList<>();
credProviders.add(new ClientUNTCredentialProvider(USERNAME.getBytes(), PASSWORD.getBytes()));

Map<String, Object> context = bindingProvider.getRequestContext();
// weblogic.xml.crypto.wss.WSSecurityContext
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
// weblogic.security.SSL.TrustManager
context.put(
WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate chain, int validateErr) {
return true;
}
}
);

threadLocalClient.set(proxy);
}





share|improve this answer


























  • I tried that approach and I get the following error: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. I also have to comment out the handler chain code, otherwise I end up with two UsernameToken and two Timestamp elements. Also this approach does not encrypt the password, it creates a PasswordText password.

    – freecouch
    Nov 13 '18 at 18:12













  • Hmm, which approach gets further, does Timestamp validation or adding a Security Token come later in the server's processing? Probably the latter. Do you have something printing out your client request so you/we can check it? If logs aren't doing that for you then you can use <SOAPMessage>.writeTo(OutputStream)

    – xtratic
    Nov 13 '18 at 18:25











  • I added the generated XML and an additional comment to the original question.

    – freecouch
    Nov 13 '18 at 18:34














0












0








0







Try this for your init() method, you may need to add a WebLogic credential provider:



private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<>();
// Add a handler to the handler chain
handlerChain.add(new PasswordDigestHeaderHandler());

BindingProvider bindingProvider = (BindingProvider) proxy;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);

// weblogic.xml.crypto.wss.provider.CredentialProvider
// weblogic.wsee.security.unt.ClientUNTCredentialProvider
List<CredentialProvider> credProviders = new ArrayList<>();
credProviders.add(new ClientUNTCredentialProvider(USERNAME.getBytes(), PASSWORD.getBytes()));

Map<String, Object> context = bindingProvider.getRequestContext();
// weblogic.xml.crypto.wss.WSSecurityContext
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
// weblogic.security.SSL.TrustManager
context.put(
WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate chain, int validateErr) {
return true;
}
}
);

threadLocalClient.set(proxy);
}





share|improve this answer















Try this for your init() method, you may need to add a WebLogic credential provider:



private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);

List<Handler> handlerChain = new ArrayList<>();
// Add a handler to the handler chain
handlerChain.add(new PasswordDigestHeaderHandler());

BindingProvider bindingProvider = (BindingProvider) proxy;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);

// weblogic.xml.crypto.wss.provider.CredentialProvider
// weblogic.wsee.security.unt.ClientUNTCredentialProvider
List<CredentialProvider> credProviders = new ArrayList<>();
credProviders.add(new ClientUNTCredentialProvider(USERNAME.getBytes(), PASSWORD.getBytes()));

Map<String, Object> context = bindingProvider.getRequestContext();
// weblogic.xml.crypto.wss.WSSecurityContext
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
// weblogic.security.SSL.TrustManager
context.put(
WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate chain, int validateErr) {
return true;
}
}
);

threadLocalClient.set(proxy);
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 13 '18 at 20:02

























answered Nov 13 '18 at 17:02









xtraticxtratic

2,4691822




2,4691822













  • I tried that approach and I get the following error: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. I also have to comment out the handler chain code, otherwise I end up with two UsernameToken and two Timestamp elements. Also this approach does not encrypt the password, it creates a PasswordText password.

    – freecouch
    Nov 13 '18 at 18:12













  • Hmm, which approach gets further, does Timestamp validation or adding a Security Token come later in the server's processing? Probably the latter. Do you have something printing out your client request so you/we can check it? If logs aren't doing that for you then you can use <SOAPMessage>.writeTo(OutputStream)

    – xtratic
    Nov 13 '18 at 18:25











  • I added the generated XML and an additional comment to the original question.

    – freecouch
    Nov 13 '18 at 18:34



















  • I tried that approach and I get the following error: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. I also have to comment out the handler chain code, otherwise I end up with two UsernameToken and two Timestamp elements. Also this approach does not encrypt the password, it creates a PasswordText password.

    – freecouch
    Nov 13 '18 at 18:12













  • Hmm, which approach gets further, does Timestamp validation or adding a Security Token come later in the server's processing? Probably the latter. Do you have something printing out your client request so you/we can check it? If logs aren't doing that for you then you can use <SOAPMessage>.writeTo(OutputStream)

    – xtratic
    Nov 13 '18 at 18:25











  • I added the generated XML and an additional comment to the original question.

    – freecouch
    Nov 13 '18 at 18:34

















I tried that approach and I get the following error: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. I also have to comment out the handler chain code, otherwise I end up with two UsernameToken and two Timestamp elements. Also this approach does not encrypt the password, it creates a PasswordText password.

– freecouch
Nov 13 '18 at 18:12







I tried that approach and I get the following error: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Timestamp validation failed. I also have to comment out the handler chain code, otherwise I end up with two UsernameToken and two Timestamp elements. Also this approach does not encrypt the password, it creates a PasswordText password.

– freecouch
Nov 13 '18 at 18:12















Hmm, which approach gets further, does Timestamp validation or adding a Security Token come later in the server's processing? Probably the latter. Do you have something printing out your client request so you/we can check it? If logs aren't doing that for you then you can use <SOAPMessage>.writeTo(OutputStream)

– xtratic
Nov 13 '18 at 18:25





Hmm, which approach gets further, does Timestamp validation or adding a Security Token come later in the server's processing? Probably the latter. Do you have something printing out your client request so you/we can check it? If logs aren't doing that for you then you can use <SOAPMessage>.writeTo(OutputStream)

– xtratic
Nov 13 '18 at 18:25













I added the generated XML and an additional comment to the original question.

– freecouch
Nov 13 '18 at 18:34





I added the generated XML and an additional comment to the original question.

– freecouch
Nov 13 '18 at 18:34


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53281854%2fpassworddigest-authentication-fails-in-jax-ws-client-running-in-weblogic%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Error while running script in elastic search , gateway timeout

Adding quotations to stringified JSON object values