-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 André,
On 3/30/17 3:41 PM, André Warnier (tomcat) wrote: > On 30.03.2017 20:10, Christopher Schultz wrote: >> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 >> >> Konstantin, >> >> On 3/30/17 4:19 AM, Konstantin Kolinko wrote: >>> 2017-03-30 11:02 GMT+03:00 Jan Vávra <va...@602.cz>: >>>> Hello, I have written a custom Realm and I need to access to >>>> the request headers. The authentication should be computed >>>> from client certificate + id from custom http header >>>> X-IdUser. Can I somehow access to the HTTPServletRequest >>>> instance ? >>> >>> Not possible, by design. >>> >>> An Authenticator (a valve) can access request and its headers. >>> A Realm cannot. >> >> I've always been frustrated by this, and it's one reason I do not >> use Tomcat's build-in authentication. I need to log >> authentication failures and their sources (IP address) and this >> information is simply not available through the Tomcat-provided >> APIs. >> >> I think there is definitely an opportunity here for improvement. >> > > A naive question or three (I can't really ask any other kind in > Java) : > > 1) what is calling the following method ? > https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/realm /DataSourceRealm.html#authenticate%28java.lang.String,%20java.lang.Strin g%29 Within > Tomcat, one of the Authenticator classes is going to be calling that method. (BasicAuthenticator, FormAuthenticator, etc.). > 2) And (assuming that if you want to do non-standard things in the > Realm, it means that you are writing your own custom Realm), isn't > there a possibility for any caller of (1) above, to pass anything > it wants in the "credentials" argument ? > > (such as a caller IP address, the content of a HTTP header, etc.) > (to be parsed out and used by the authenticate method, for logging > e.g.) Absolutely, you could do that. But let's say that I want to write my own Realm implementation so I can e.g. write the user's IP address to a table when they authenticate. Okay, I write a Realm but the interface doesn't contain any of that data. So, I decide that I want to package the IP address into the username field for authenticate(String username, String password). Sounds good, but then I'd need to write my own Authenticator that knows that the username is actually IP-address + username instead of just username like usual. And if I'm going to write my own Realm *and* Authenticator, why don't I just write everything myself and skip the Tomcat-provided code? > 3) and, still assuming much, might one then perhaps use this > element to specify a class which would perform ditto parsing, prior > to the authentication itself ? > http://tomcat.apache.org/tomcat-9.0-doc/config/credentialhandler.html The > CredentialHandler's job is to take the user's credential (the password) and compare it to the value that was stored in the user database. Providing a custom CredentialHandler only allows you to support different types of password-munging. Note that the CredentialHandler doesn't have access to any data storage system (like the user database). The Realm is designed to fetch the user's stored credential from the user database and then delegate the comparison to the CredentialHandler. This allows someone to support e.g. a hashing algorithm that Tomcat has never seen before. But it doesn't allow the user database to store anything new. Tomcat is attempting to separate the concerns of various things into separate classes / interfaces. This allows a great deal of re-use of code. For example, there are "authenticators" (which don't authenticate) for the following: HTTP Basic, HTTP Digest, CLIENT-CERT, FORM. And there are Realms (which actually authenticate) for the following user databases: JDBC, DataStore(also JDBC), LDAP/JNDI, JAAS, and "memory" (really "file"). If there was one class for each setup, you'd need an explosion of classe s: HttpBasicLDAPAuthenticator HttpBasicJDBCAuthenticator HttpBasicDataSourceAuthenticator HttpBasicJAASAuthenticator HttpDigestLDAPAuthenticator HttpDigestJDBCAuthenticator HttpDigestDataSourceAuthenticator etc. There are some authenticators that only make sense for some realm methods. For example, the SSLAuthenticator is never going to call Realm.authenticate(username, password). So in a way, these interfaces are already a bit "impure". But the idea for the Realm was "let's have a class/interface whose job is simply to say yes/no to authentication requests and also to determine if a user is authorized for a role-based permission". There's really no reason to make that HTTP-specific. What does it mean to have a username and password that match with or without an IP address ? There is nothing HTTP-specific about a Realm, which is why this complexity is left-out of the Realm interface. But some people need their applications to use some information available from the HTTP request as part of their authentication (or, possibly their authentication-failure) processes. So the solution currently requires programmers to step outside of Tomcat's existing code and built a lot of their own things from scratch. This used to be the case if you wanted to use a different hashing algorithm (e.g. bcrypt): you'd have to write your own Realm mostly from scratch and repeat a lot of code from the existing Realms. That's why we introduced the CredentialHandler: so users could customize that that /little/ piece of the puzzle. (It's also got some other goodies in there like being able to access the CredentialHandler from application code, so you can use the same configuration for authentication as you do for changing user passwords within the application.) I think the same thing can be done for the authenticator-realm relationship so that other information can be available for the Realm to do its work. We just need to come up with a reasonable use-case and a solution to it that doesn't require dozens of new classes/interfaces. It is quite easy to over-design something in an OO language :) - -chris -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJY3pShAAoJEBzwKT+lPKRYA3IP/juTSFRqZ4DAfddadPPfykqI ibcIIC85f2pI+WgAqnNPBs3sbfcmGlFA6uQwxuDKsYO70JSr9xROjMZUU+6Uk3s5 z1PA+hqxZKtsNh+Rg3y6I+jDNywG/3eP2rYrYmuDAtdp3Q67llsKsFQ8FN3SKdw8 mrvtJNqhIJCBhZMLctGjvMPVZiwkYQXhnhAB8z2eTwy/CjWmP28ciazguspqI2OX xfcdILqK8ggwhgKhF/ANcjnNXZCo3kQ5KwMumySbp/iSGCBHa+v555kU2dm4go+D H4GSuZMtvTPhIfSQVVRiIdS7V0AtF7De5qgsFIC4jbffoXCePp+Zgy2B8cvVDDcg PIQs2HFlvb+I/EfSNiLZEfJ8YUzcNy9+u0MGGehFqnxblDOYeAHWCwDIvU6Uk/oo UFQARuxWyG20PUdF7vbsOGrsoXxadqQdSBbecpRnCpefQrWtTFB9M49/gZy3u5mw jG0kZ1k0sKggwGl14DovDad2gjitm/z2lj2YDEoNC4l8gxRp+G77i16x+ZH+PuW/ 4/Cryo+ECruw++GVXmKmpWRjv/p1HVLnnL56ADxJRlNx9Gb05rM3d9tE1LkoVAqx iR5TOueiDiH69CjWW1owFKaiVeVc1cIH+lFFI5MuNN2jsTCWYHblTvIzCm0J/7RS pDW7cMnDxAwZerfpnt1W =O8LD -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org