Java Client for WCF on HTTPS - java

I can't figure out how to proceed for the next scenario.
I have a WCF service up and running with security like this:
<binding name="SSLBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
<!--<message clientCredentialType="UserName"/>-->
</security>
</binding>
I was able to make a dummy ceritificate in the IIS 5.0, so this WCF can be exposed on HTTPS.
Finally using a .Net client I can communicate with the Service, something like this:
private void randomMethod
{
//This is necesary, cause the certificate isnĀ“t valid
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);
RefHTTPS.GestionesServiceClient service = new RefHTTPS.GestionesServiceClient();
richTextBox1.Text = service.version();
}
public static bool IgnoreCertificateErrorHandler(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
ISSUE: When I try to do this on a Java client I get Exceptions.
Someone has been able to do something like this, I need some guidance here.
I read a lot of posts on the web, but nothing works for me.
Edit (merged from additional content from OP, was posted as a question and flagged):
This is the full config (it has a config tag, but isn't showing):
<?xml version="1.0"?>
<system.web>
<compilation debug="true">
</compilation>
</system.web>
<system.serviceModel>
<bindings>
<binding name="SSLBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</bindings>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="https://x.x.x.x"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<services>
<service behaviorConfiguration="WSGestiones.GestionesServiceBehavior" name="WSGestiones.GestionesService">
<endpoint address="https://x.x.x.x/GestionesWS/GestionesService.svc"
binding="basicHttpBinding" bindingConfiguration="SSLBinding" contract="WSGestiones.IGestionesService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="https://x.x.x.x/GestionesWS/GestionesService.svc/mex"
binding="mexHttpsBinding" contract="IMetadataExchange">
<identity>
<dns value="IPADDRESS" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WSGestiones.GestionesServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl="https://x.x.x.x/GestionesWS/GestionesService.svc" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
I was able to add the certificate to the trusted list of my PC, I also added to the JDK or wherever in Java.
Some of my errors was:
Exception in thread "main" javax.xml.ws.WebServiceException: Cannot find 'https://x.x.x.x/GestionesWS/GestionesService.svc?wsdl' wsdl. Place the resource correctly in the classpath.
HTTP transport error: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: java.io.IOException: HTTPS hostname wrong: should be <x.x.x.x>
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: An error occurred when verifying security for the message.
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Access Denied
Every time I hit an error, searched online and "fixed", a new one appears....in my 5th day of "fixes" I say "this is an infinite loop".
So....instead of trying to fix the errors, I was thinking of "fixing the logic".

I was also trying to connect to a server with a self-signed certificate for a service endpoint via Netbeans. When I tried to make a new connection object, I came across this runtime exception:
javax.xml.ws.WebServiceException: java.io.IOException: HTTPS hostname wrong: should be <hostname as in the certificate>
And I finally found a section about this exception in Metro's documentation. The code they provide unfortunately looks like it's intended only to be a temporary solution, but at least it looks like you can get around this issue.
I modified the code they provided by creating a static method that I call at the top of my main method where I always 'verify' the site I connect to for my service:
private static void overrideDefaultHostnameVerifier() {
//WORKAROUND. TO BE REMOVED.
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier() {
#Override
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return true;
}
});
}
The true solution to this problem looks to be getting a real issued certificate on the server hosting the service endpoint.

Related

Can a SSLHandshakeException be a retry-able exception?

I have a service-to-service connection that is intermittently throwing SSLHandshakeExceptions from a jersey client.
public static class MyClientFilter extends ClientFilter{
#Override
public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
try {
return getNext().handle(cr);
} catch (ClientHandlerException e) {
Throwable rootCause = e.getCause() != null ? e.getCause() : e;
if (ConnectException.class.isInstance(rootCause) ||
SocketException.class.isInstance(rootCause) ||
SSLHandshakeException.class.isInstance(rootCause) //maybe?
) {
//do some retry logic
}
}
}
}
The fact that it is only happening intermittently (very rarely) says to me that my certificates and TLS are all configured correctly. In my client I am attempting to retry connections if they fail due to connection or socket exceptions. I am considering making an SSLHandshakeException also a retry-able exception because in my case it seems like it should be, but I am wondering if an SSLHandshakeException could be caused by a connection or socket issue and, if so, is there a way to tell?
Update:
The message of the exception seems to indicate that it could be a connection issue that is not related to SSL configuration:
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:249)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:149)
... 44 common frames omitted
Can a SSLHandshakeException be a retry-able exception?
It is not entirely clear what you are asking:
Does SSLHandshakeException itself retry? No. Of course not.
Are you permitted to retry a connection attempt following a SSLHandshakeException? Yes, you are permitted to retry.
Is advisable to retry? It probably will just fail again, but it depends on what is causing the connection to fail.
Is advisable to retry repeatedly? Definitely not.
Really what this boils down to is diagnosing the cause of the connection failures. To do this you will need to enable client-side debug logging for the SSL connections.
A common cause for this kind of problem is that the client and server cannot negotiate a mutually acceptable SSL/TLS protocol version or cryptographic suite. This typically happens when one end is using an old SSL / TLS stack that is (by current standards) insecure. If this is the root cause then retrying won't help.
It is also possible ... but extremely unlikely ... that the server or the network "glitched" at just the wrong time.
The message of the exception seems to indicate that it could be a connection issue that is not related to SSL configuration.
Actually, I doubt it. It is standard behavior for a server to simply close the connection if the negotiation has failed; see RFC 8446 Section 4.1 for the details. The client will see that as a broken connection.

Mule: Remote Dispatcher fails on Deserialization at the Server

We have a Mule Service running on a server. I am developing a stand alone Mule Client that connects directly into the Mule service.
When I run the client, I am receiving the below error:
ERROR 2015-09-23 10:36:02,724 [[cheetah-web-services].connector.http.mule.default.receiver.03] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Failed to transform from "byte[]" to "Object"
Type : org.mule.api.transformer.TransformerException
Code : MULE_ERROR-109
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html
Transformer : ByteArrayToMuleMessage{this=1574dd9, name='null', ignoreBadInput=false, returnClass=SimpleDataType{type=org.mule.api.MuleMessage, mimeType='*/*'}, sourceTypes=[SimpleDataType{type=[B, mimeType='*/*'}, SimpleDataType{type=java.io.InputStream, mimeType='*/*'}]}
********************************************************************************
Exception stack is:
1. com.mycompany.myapp.service.model.ServiceSearch; class invalid for deserialization (java.io.InvalidClassException)
java.io.ObjectStreamClass$ExceptionInfo:150 (null)
2. java.io.InvalidClassException: com.mycompany.myapp.service.model.ServiceSearch; class invalid for deserialization (org.apache.commons.lang.SerializationException)
org.mule.util.SerializationUtils:85 (null)
3. Failed to transform from "byte[]" to "Object" (org.mule.api.transformer.TransformerException)
org.mule.transformer.simple.ByteArrayToSerializable:54 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html)
********************************************************************************
Root Exception stack trace:
java.io.InvalidClassException: com.mycompany.myapp.service.model.ServiceSearch; class invalid for deserialization
I have setup a remote dispatcher agent on the server.
<client:remote-dispatcher-agent>
<client:remote-endpoint address="http://localhost:20809" exchange-pattern="request-response" responseTimeout="10000"/>
I have created a separate mule client.
<client:remote-dispatcher-agent>
<client:remote-endpoint ref="remoteDispatcherChannel" />
<client:xml-wire-format/>
</client:remote-dispatcher-agent>
<http:endpoint name="remoteDispatcherChannel"
host="localhost"
port="20809"
path="_remoting"
exchange-pattern="request-response" />
Below is the Client Code. The ServiceSearch object implements all Serializable.
MuleClient muleClient = new MuleClient(true);
RemoteDispatcher dispatcher2 = muleClient.getRemoteDispatcher("http://127.0.0.1:20809/_remoting");
MuleMessage result = dispatcher2.sendToRemoteComponent("myAppServiceDelegate", ServiceSearch, msgMap);
Below is the Mule Service flow on the server I am trying to get into. I am coming in on the invoker step. I choice this step as I could sent the object directly to the service in the required format
<flow name="post:/service/search:my-web-services-config" initialState="started">
<logger level="INFO" doc:name="Log Request Properties" message="Request Type: #[message.inboundProperties.'http.method'], Request Path: #[message.inboundProperties.'http.request.path'], Request Params: #[message.inboundProperties.'http.query.params']" />
<json:json-to-object-transformer returnClass="com.mycompany.myapp.service.model.ServiceSearch" ignoreBadInput="true" mimeType="application/json" doc:name="Request JSON to ServiceSearch" />
<invoke object-ref="myappServiceDelegate" method="processSearch" methodArguments="#[payload],#[flowVars.'CLIENT_ID']" doc:name="Calling Search Delegate" />
<logger message="Generated DSL: #[payload.queryDSL]" level="INFO" doc:name="Log Query DSL" />
<flow-ref name="BigDataSearchFlow" doc:name="Big Data Flow" />
<exception-strategy ref="globalResponseExceptionStrategy" doc:name="Reference Exception Strategy" />
</flow>
I would appreciate some feedback on this approach and suggestions on what I should look for in the ServiceSearch object.
Russ
You are using an order/newer version of com.mycompany.myapp.service.model.ServiceSearch or none at all at the server side.
Please make sure both ends do have the very same version of the file.

Web-service client on Websphere throws NullPointer on method calling

We've been using
jaxws-spring
WebSphere 8.5.5.2
for our web-services interactions, and now we get stuck with such "cause" when we call any web-method on the client-side -
ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause appServlet:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.xml.ws.soap.SOAPFaultException: java.lang.NullPointerException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
.....
Caused by: javax.xml.ws.soap.SOAPFaultException: java.lang.NullPointerException
at org.apache.axis2.jaxws.marshaller.impl.alt.MethodMarshallerUtils.createSystemException(MethodMarshallerUtils.java:1363)
at org.apache.axis2.jaxws.marshaller.impl.alt.MethodMarshallerUtils.demarshalFaultResponse(MethodMarshallerUtils.java:1089)
at org.apache.axis2.jaxws.marshaller.impl.alt.DocLitWrappedMethodMarshaller.demarshalFaultResponse(DocLitWrappedMethodMarshaller.java:680)
at org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler.getFaultResponse(JAXWSProxyHandler.java:626)
....
Caused by: java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:946)
at org.apache.axis2.jaxws.message.databinding.JAXBUtils.getJAXBContext(JAXBUtils.java:445)
at org.apache.axis2.datasource.jaxb.JAXBDSContext.getJAXBContext(JAXBDSContext.java:228)
at org.apache.axis2.datasource.jaxb.JAXBDSContext.getJAXBContext(JAXBDSContext.java:161)
at org.apache.axis2.datasource.jaxb.JAXBDSContext.marshal(JAXBDSContext.java:396)
at org.apache.axis2.jaxws.message.databinding.impl.JAXBBlockImpl._outputFromBO(JAXBBlockImpl.java:189)
at org.apache.axis2.jaxws.message.impl.BlockImpl.outputTo(BlockImpl.java:371)
at org.apache.axis2.jaxws.message.impl.BlockImpl.serialize(BlockImpl.java:295)
at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.internalSerialize(OMSourcedElementImpl.java:781)
at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:967)
at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.serializeInternally(SOAPEnvelopeImpl.java:283)
at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:245)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.serializeAndConsume(OMSerializableImpl.java:207)
at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:74)
Web-service client initialisation comes out with no any errors -
URL service_endpoint;
service_endpoint = new URL(endpoint);
service = new UDHandlersServiceImpl(service_endpoint, SERVICE_QNAME).getUDHandlersServiceImplPort();
NullPointerException occurs after calling any method of "service". And it doesn't even reach server side - because it doesn't have any logs there. Furthermore - such situation occurs only on the WebSphere - we deployed our client application on the Tomcat (server remained on websphere) and it worked fine. One more thing - SoapUI does not have any problems interacting with server side too.
We tried to switch classLoadings to parentLast for client application - with no success.
Also I can't even find sources for "org.apache.axis2.jaxws.message.databinding.JAXBUtils.getJAXBContext(JAXBUtils.java:445)". I googled it and didn't find this version of JAXBUtils. But even if i did, i think, it wouldnt be useful...
I hope someone can help us with that unobvious problem.
Thanks beforehand.
===== updated======
When we remove jaxb libraries from endorsed dir (or appServer/classes) problem seems to disappear but in case of arising webExceptions(faults) server throws
Caused by: java.lang.ClassCastException: com.ibm.xml.xlxp2.jaxb.JAXBContextImpl incompatible with com.sun.xml.bind.api.JAXBRIContext
at com.sun.xml.ws.fault.SOAPFaultBuilder.<clinit>(SOAPFaultBuilder.java:565)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:237)
and returns no answer to the client.
We've realized that our exceptions didn't contain 3 required methods -
//============required==================
public DocumentValidationException(String message, ErrorsBean errorsBean, Throwable cause) {
super(message, cause);
this.errorsBean = errorsBean;
}
public ErrorsBean getFaultInfo() {
return errorsBean;
}
public DocumentValidationException(String message, ErrorsBean errorsBean) {
super(message);
this.errorsBean = errorsBean;
}
//======================================
so, now it does.
And also we had some wrong target namespaces in it at the #WebFault annotations.
Here is the link with similar problem - https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014076927#77777777-0000-0000-0000-000014083314

Polling HTTP endpoint followed by jersey REST WS does not work in Mule 3.5

I have a requirement where i need to poll a rest service and then proxy the response from this web service on to a REST web service.
I am using Mule 3.5 and my flow looks like the below.
I get the below exception where the REST service is being invoked
********************************************************************************
Message : Failed to invoke JerseyResourcesComponent{TestFlow.component.1106552446}. Component that caused exception is: JerseyResourcesComponent{TestFlow.component.1106552446}. Message payload is of type: String
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. null (java.lang.NullPointerException)
org.mule.module.jersey.JerseyResourcesComponent:192 (null)
2. Failed to invoke JerseyResourcesComponent{TestFlow.component.1106552446}. Component that caused exception is: JerseyResourcesComponent{TestFlow.component.1106552446}. Message payload is of type: String (org.mule.component.ComponentException)
org.mule.component.AbstractComponent:144 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/component/ComponentException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.NullPointerException
at org.mule.module.jersey.JerseyResourcesComponent.getBaseUri(JerseyResourcesComponent.java:192)
at org.mule.module.jersey.JerseyResourcesComponent.doInvoke(JerseyResourcesComponent.java:146)
at org.mule.component.AbstractComponent.invokeInternal(AbstractComponent.java:122)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
After debugging i figured out it is because Mule expects the MuleMessage inbound property for contextPath to be populated however in this case it is null.
In JerseyResourcesComponent line 117 is returned as null and hence line 195 throws a NPE.
I wanted to know if this kind of requirement/pattern is invalid or is it some kind of limitation in the way Mule is handling its messaging infrastructure ?
The flow xml just in case you want to inspect it.
<flow name="TestFlow" doc:name="TestFlow">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="10" timeUnit="SECONDS" startDelay="10"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8080" doc:name="Order Generator" method="GET" contentType="application/json" path="order"/>
</poll>
<object-to-string-transformer doc:name="Object to String"/>
<jersey:resources doc:name="Tax Calculator">
<component class="org.nthdimenzion.TaxCalculator"/>
</jersey:resources>
<logger level="INFO" doc:name="Logger"/>
</flow>
PS : The work around i got was to use a java/spring component instead of a REST WS and then call the REST WS from the Java component.

Using Apache Rampart for Signature with JKS and Binary Security Token key identifier

I have to call a web service that was provided by a customer (some information below is masked for this reason). I've been provided with a java keystore that contains the private key that I need to use to generate a signature to include in the WSSecurity header of my request.
Additionally, I've been sent a working SoapUI project that implements this service with the proper security configuration. The outgoing security configuration in soapUI has the "Key Identifier Type" set to "Binary Security Token"
I am trying to set this call up in my Java application using Apache Rampart. I noticed that there is no equivalent to "Binary Security Token" key identifier in the OutflowSecurity configuration, so I'm trying the following. Here is the relevant snippet from my axis2.xml file:
<module ref="rampart" />
<parameter name="OutflowSecurity">
<action>
<items>Signature</items>
<user>*******</user>
<passwordCallbackClass>*******.PWCBHandler</passwordCallbackClass>
<signaturePropFile>crypto.properties</signaturePropFile>
<signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
</action>
</parameter>
And here are the contents of my crypto.properties file:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.file=C:/rampart/*****.jks
org.apache.ws.security.crypto.merlin.keystore.alias=******
org.apache.ws.security.crypto.merlin.alias.password=**********
org.apache.ws.security.crypto.merlin.keystore.password=********* (same as above)
The issue is that when I try to execute the service with this configuration, I get the following error:
org.apache.axis2.AxisFault: Error during Signature:
at org.apache.rampart.handler.WSDoAllSender.processMessage(WSDoAllSender.java:75)
at org.apache.rampart.handler.WSDoAllHandler.invoke(WSDoAllHandler.java:72)
at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
at org.apache.axis2.engine.Phase.invoke(Phase.java:313)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:262)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:427)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
... (removed)
Caused by: org.apache.ws.security.WSSecurityException: Error during Signature:
at org.apache.ws.security.action.SignatureAction.execute(SignatureAction.java:64)
at org.apache.ws.security.handler.WSHandler.doSenderAction(WSHandler.java:202)
at org.apache.rampart.handler.WSDoAllSender.processBasic(WSDoAllSender.java:212)
at org.apache.rampart.handler.WSDoAllSender.processMessage(WSDoAllSender.java:72)
... 13 more
Caused by: org.apache.ws.security.WSSecurityException: Signature creation failed
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:558)
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:478)
at org.apache.ws.security.message.WSSecSignature.build(WSSecSignature.java:384)
at org.apache.ws.security.action.SignatureAction.execute(SignatureAction.java:61)
... 16 more
Caused by: org.apache.ws.security.WSSecurityException: General security error (The private key for the supplied alias does not exist in the keystore)
at org.apache.ws.security.components.crypto.Merlin.getPrivateKey(Merlin.java:725)
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:501)
... 19 more
Caused by: java.security.UnrecoverableKeyException: Cannot recover key
at sun.security.provider.KeyProtector.recover(Unknown Source)
at sun.security.provider.JavaKeyStore.engineGetKey(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineGetKey(Unknown Source)
at java.security.KeyStore.getKey(Unknown Source)
at org.apache.ws.security.components.crypto.Merlin.getPrivateKey(Merlin.java:711)
... 20 more
I've tried all of the different signatureKeyIdentifiers options without any luck. Could anyone help me perhaps figure out where to go from here to debug this issue?
Thank you!
I'm not sure about your overall configuration, but the obvious problem is that the alias that you use to load the key from keystore is invalid. Maybe you use alias of some public key instead of private? Rampart will use user as key alias when alias itself is not provided, so I would make sure that both, user in service configuration and alias in properties, are set to the same value.
You can verify which one to use by listing keystore contents using keytool from JDK:
JDK/bin/keytool -list -keystore path/to/keystore
It should print:
alias1, 13-May-2013, trustedCertEntry, (public key only, used to verify signature)
Certificate fingerprint (SHA1): *****
alias2, 13-May-2013, PrivateKeyEntry, (private/public key pair, used to sign messages)
Certificate fingerprint (SHA1): *****
Questions:
1. Do we need to make any other configurations other than the policy files.
2. If so, where we need to add it.
3. Can you review the policy file is fine for the requirement with binary security token.
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>***</ramp:user>
<ramp:passwordCallbackClass>com.sosnoski.ws.library.adb.PWCBHandler</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file">com/sosnoski/ws/library/adb/***.jks</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">******</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
Fixed. I had the wrong username in my password callback handler. It wasn't able to find the password to use to access the key.. Thanks for the help. Sorry for the late answer. I had it as a comment to the originating question before.

Categories