I've got a web service which may be bound either to ssl or plain http. The java clients configured to know the server host and port. When client connects, I construct the server end point like http://host:port/service. Clients don't have a knowledge whether the server is using ssl - server always binds to a single port so that it's either secure or not. Now, the question is how to make a client to discover this without introducing another parameter? Can I challenge plain http request and then fall back to ssl (or vice verse) on a certain exception? Or I must explicitly introduce new connection parameter for the clients?
问题:
回答1:
On the server side, you could use a mechanism like Grizzly's port unification implementation. This can be used to serve HTTP and HTTPS on the same port. This relies on the fact that in both cases, the client talks first and either sends an HTTP request or an SSL/TLS Client Hello message. It's quite handy for this on the server side (although I'm not sure I'd recommend running two protocols on the same port in general).
From the client's point of view (which is what you're asking about), the consequences of that are:
- The fact that the client talks first means that it will always have to try first. Expect an exception of some sort if you try to talk SSL/TLS to a plain HTTP service and vice versa.
- If the server uses port unification, there is no way you're going to be able to find out reliably.
Port unification aside (this is a rare case after all), you could try to cache results of past attempts.
More fundamentally, from a security point of view, not knowing which protocol should be used introduces a vulnerability: your system will be open to downgrade attacks (in a similar way as blindly relying on automatic redirects would). If your user-agent supports HSTS, it would be worth looking into that (although it would require the user-agent to remember which sites are to be used with HTTPS).
Either way, if you're concerned about security, you must configure the client to know when to use https://
.