-----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