-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

James,

On 12/19/18 20:18, James H. H. Lampert wrote:
> I just had a crazy thought, in connection with a situation in
> which we're trying to figure out a way to limit web service
> connections to authorized consumers.
> 
> Here's the situation: we have both a browser-based UI (for which
> we definitely do NOT want to require users to have client-side
> certificates installed in their browsers), and a series of web
> services (for which we want to be able to restrict any given
> user-ID and password to consumer-side hardware authorized for that
> given user-ID and password).

All in the same webapp, or deployed in separate webapps?

Note that you won't be able to verify that the hardware is actually
"authorized". If you want mutual TLS auth, then you are only
authenticating the client certificate and not really anything else
about the client. You probably know that and/or don't care, but I
thought I'd mention it in case it's important to you.

> For situations in which a given customer's users are calling the 
> services from their own hardware, at their own IP address, that's
> not a problem. For situations in which the web services are being
> consumed by *a specific* cloud server with *a specific, permanent,
> IP address*, it's not a problem: either way, we can simply
> authorize that IP address for that customer's user-IDs.

IP-based authentication isn't a great way to do things. It's very
fragile and hostile to users (even automated "users") because they
can't relocate without coordinating with you.

> But what if the services are being consumed by a cloud server
> that's part of a managed, load-balanced, instance group? I know
> empirically that such a box, at least if it's a Google Compute
> instance, calls the services from its own external IP address.

Correct. Traffic exiting the VLAN will appear to have the public IP of
the gateway.

> Could it be done with something involving presentation of the
> public key of a certificate, without forcing browsers accessing the
> UI to also do so?

Mutual TLS is definitely possible. It requires that all clients have
their certs installed on the clients (along with their private keys!)
and that either (a) the server trusts each key individually or (b) the
server trusts the cert that was used to sign the client certificates.
That means you basically have to set up your own CA and sign certs for
your clients. It's not actually that bad once you know what you are
doing, but it's important to know that you'll have to do that kind of
thing.

Tomcat manages client-cert authentication with an SSLAuthenticator
object, which is a Valve which gets automatically added to the
application if you specify CLIENT-CERT authentication in your
application's web.xml file. You can also add it manually via
configuration or code during startup.

Tomcat's <Connector> needs to know whether or not to ask the client
for a cert. You do that using the "clientAuth" attribute on the
<Connector> (which is now the certificateVerification attribute on the
<SSLHostConfig> element as of 8.5.x).

You will have to decide if you want Tomcat to demand a certificate or
only to ask nicely for a certificate. If you want to have a single
<Connector> where both humans and robots can authenticate in their own
way, you'll have to set certificateVerification="optional" meaning
that the client won't be forced to provide a certificate. If a
certificate *is* presented, it will be verified by the normal process.

(Actually, I'm a little unclear here if you need the
SSLAuthenticator(Valve) or if configuring the <Connector> for
client-cert verification is enough. I suspect that you may be able to
get away with just the client-cert config on the
<Connector>/<SSLHostConfig> without the authenticator valve).

Anyhow, all users will present a username+password, right? So they
will authenticate themselves to either Tomcat or your application
using that facility, and the client-cert is just for "certain parts of
the web application". The last piece is to put a Filter on your
application that grabs the client-cert from the request attributes to
check for its presence. If Tomcat does not perform the verification
for whatever reason, you'll have to verify it yourself.

I wrote-up some work I did about 10 years ago to do this, but I was
using httpd as a reverse-proxy and "requesting" the
client-certificate. mod_jk and Tomcat are simply providing the
certificate to the application without any checking at all. I
documented it here:
https://markmail.org/message/kzxsamuiu6bldjmv

There is some code in there that shows you how to check a certificate
in the request against the system's default trust store. That's
probably not what you want: you probably want a separate trust store
that only stores the certs you actually trust for this service. Rather
than trying to put too much in this post (too late!), I'll leave that
bridge to be crossed in the future.

Hope that helps,
- -chris
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlwbGmgACgkQHPApP6U8
pFhZJA//dnf4A5Tl6c+ikz2lXvc4PL42kClKOVAJLlMtGKJpg9aC/0IhOmUoWs9W
O3YDwNiaez24QmdOIYS3BIn/wGGY/sEdowEC1MZs8RMDGEPcwMCJQkB9ZfVf6gnN
fxtJJ4cec2cJXYO2L/dnSaj04zZWiwEcPV1jwjVE+5Hk8+8rOXqf2z5tFnsmySCm
Kn2D93nEM2AdezVW+rR+VxwxXPthtk9LWHSVoWuExnHlwQqpO5u2tcRDMgWcjgdq
XIR6jYI5QHyyK6HmZzVd3U0Mdjhy9sLcyfIpd3Vq5FxkQ5MlMglXuJqOJgKYi9hO
Lj/un7WPbhv97SZighMzOGfvC4FVHwEU+Gh/dsEPHTyomVEmprf/CPUzZTqm9IDp
qshD5U7rDtL9NYG6jRM0Q65E6K6N9Kwkv0VyXnQKXML2gBgbMlhpsD9ZfxBRgsmK
bqKTlSFjfkM0H6kY1Chlba2pDQDxZNyynO6kKsCbpJTv151hZusdwR/Jrjf33boO
j3gPkZuBeGK6Y1rw8XhsyhzTsN8mEHdwUiEVJhga1mEsubvrhTUUAowNlfnEnAuf
wqAl1ElwY3EPjCNA/Jei//K5CuRIStIDnc4RbNPzQRXPakSC2Uiz2rd26EfOFUH9
RYoo3xdjPISlvR7Ce7xAbEZJBghcXqL7oNcTgIGe/dCdIkIO2+8=
=Z6Uc
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to