简体   繁体   中英

2-way SSL for web services on GAE (java)

We need to implement two-way SSL on Google App Engine, where we send out web service requests using JAX-WS to a server requring 2-way SSL authentication.

How can we set up 2-way SSL for our outgoing web service requests?

We know that javax.net.ssl* is forbidden in the App Engine environment.

Here's an example of our code:

@WebService(name="ListenerSoap", targetNamespace = "http://example.com/Listener.Wsdl")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ListenerSoap {

    @WebMethod(operationName = "Ping", action="http://example.com/Listener.Wsdl#Ping")
    public void ping();
}

@WebServiceClient(name="Listener", targetNamespace="http://example.com/Listener.Wsdl", wsdlLocation = "https://example.com/Listener.asmx?WSDL")
public class Listener extends Service
{
  public ListenerSoap getListenerSoap() {
   return super.getPort(new QName("http://example.com/Listener.Wsdl", 
                       "ListenerSoap"), ListenerSoap.class);
  }
}

And an example of above code in use:

ListenerSoap soap = new Listener().getListenerSoap();
soap.ping();

I figure we can store the keystores or any certs needed in the DataStore as binary objects (though how to upload them is still a lil' vague to me).

How can we go about setting the necessary values needed for this web service to authenticate using 2-way SSL?

Thanks for any help

Update:

Through research I've seen this is how it can be done on a traditional server (one with filesystem access):

ListenerSoap soap = new Listener().getListenerSoap();
((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore", "client_cert.p12"

However, in this approach, client_cert.p12 is expected to be on the filesystem.

Additionally, SSLSocketFactory , SSLContext , KeyManager , and KeyManagerFactory all aren't allowed on GAE.

Update:

As of GAE SDK version 1.7.7. this should now be possible:

Similarly, Java developers can now use the javax.net.ssl package to make outbound SSL connections.

GAE 1.7.7 SDK Release Notes

From my restricted knowledge about SSL authorization, it seems you may be missing something of vital importance here; the certificates. Two-way SSL requires the client and server certificates to be in your keystore, which can be either a self-signed certificate( a pkcs12 or pem file, which you can easily generate with a few commands through shell) or a proprietary certificate issued by an authorized company like Thawte or Verisign. Although I am not sure if that is the problem you are facing, but its good to check it out. (Also, I am a newbie so please don't downvote my answer, just trying to suggest possible options.)

ListenerSoap soap = new Listener().getListenerSoap();

Hope it improves

Thanks

I know you might not want to hear this, but using SSL is expensive and problematic for two way communication. Depending on how much control you have over the server/client ends, I prefer a simple bi-directional pipe like web sockets and a data packet protocol that can simply implement AES. It really depends on the problem you are trying to solve.

It sounds like there is confusion over simple connection over SSL ( https://... ) and what is known as "mutual authentication" or "public key infrastructure (PKI)". You can actually do both or one independent of another. With the latter (what I think the original question is referring to), when you make a request to the server, the server will respond to you asking for a certificate which you must present to authenticate yourself.

To answer the specific question above (loading a keystore from binary data), I don't think that is really possible, since it's the Java runtime that picks up on your keystore. The only think you could do is load the bits from your datastore and temporarily write it to disk. Optionally delete it when the application exists. This I have done before and works fairly well. If you do this, I'd recommend using a location likely to be writable (such as System.getProperty("java.io.tmpdir")); ), then after writing the file to disk, set the JVM properties (eg System.getProperties().put( "javax.net.ssl.keyStore","..."); )

You will need App Engine's Socket API for this. This API is in trusted tester mode, so it's not available for everyone.

You can ask for an access gere : https://docs.google.com/spreadsheet/viewform?formkey=dF9QR3pnQ2pNa0dqalViSTZoenVkcHc6MQ#gid=0

2-way SSL (from app hosted in GAE to outside world) is not supported as far as I know. I tried a sample app few months ago and was frustrated to find GAE does n't even support this basic feature.. and the documentations are n't clear either. You won't be able to present client cert when you contact a web-service.. there is no place to store it, the keystore cannot be accessed.

For what i know about two way SSL, you will have no link with Java EE code: two way SSL is a transport layer security: when your client application will try to create a secured HTTP connection (HTTPS) with the serve, the server will ask for a certificate and will approve or not this certificate. If the client certificate is approved, then a secured connection will be established on parties and they are allow to exchange some messages through this tunnel. But this process is done on the transport layer. Your code (on application layer) will never be informed of this process. In order to established two way SSL, the setup is done on the application server setup for the SSL port.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM