Re: Switching basic auth to client-cert with realms - how?
Graham, On Fri, Mar 13, 2015 at 3:39 PM, Graham Leggett minf...@sharp.fm wrote: Hi all, I have a basic authentication setup that works great as below. login-config auth-methodBASIC/auth-method realm-namePatricia/realm-name /login-config !-- Security roles referenced by this web application -- security-role role-nameadministrator/role-name /security-role security-role role-nameunderwriter/role-name /security-role security-role role-nameaccountant/role-name /security-role security-role role-namebroker/role-name /security-role security-role role-namefeeds/role-name /security-role It is backed up with a realm like this: Realm className=“org.apache.catalina.realm.DataSourceRealm [snip] userTable=person userNameCol=mail userCredCol=user_password userRoleTable=company_person roleNameCol=serial / I need to switch basic authentication to client certificates, as provided by Apache httpd and proxied in with AJP. The username is provided by Apache httpd in REMOTE_USER. In theory, changing the auth-method to CLIENT-CERT should do the trick, but I just get forbidden. What doesn’t seem to fit is the realm definition - specifying userCredCol is marked as mandatory, but this is obviously not present with a client certificate. What do you specify in this field? Does anyone have a working example of authentication using client certificates and authorization using a realm backed with a DataSource? Here's a nice article, detailing how to add CLIENT-CERT: http://java.dzone.com/articles/enabling-client-cert-based It is based on MemoryRealm, not DataSourceRealm, but the idea is similar. Here's a summary: 1. You need to define user/pass/roles: role rolename=secureconn/ user username=CN=client1, OU=Application Development, O=GoSmarter, L=Bangalore, ST=KA, C=IN password=null roles=secureconn/ 2. You define in web.xml the login type: login-config auth-methodCLIENT-CERT/auth-method realm-nameDemo App/realm-name /login-config You would get a 403 if an invalid certificate is sent based on the security constraints you set earlier. Ultimately, you need to turn on extra logging on that realm so you would know why the 403s were generated. Try doing some online searching for the type of errors you got. Here's what pops up in my quick google search: http://stackoverflow.com/questions/5086457/setting-up-client-cert-authentication-with-roles-on-tomcat-6-0 This person had an issue how CNs were handled, and as a result extra inserted spaces between commas, e.g. (1) no spaces: CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU (2) with spaces: CN=testuser, O=Internet Widgits Pty Ltd, ST=Some-State, C=AU The issue was how X509Principal.getName() call returned: X500Principal.RFC2253 X500Principal.RFC1779 Let us know what you find by turning on extra logging. Cheers! Neven
Re: Switching basic auth to client-cert with realms - how?
Graham, On Fri, Mar 13, 2015 at 3:39 PM, Graham Leggett minf...@sharp.fm wrote: What doesn’t seem to fit is the realm definition - specifying userCredCol is marked as mandatory, but this is obviously not present with a client certificate. What do you specify in this field? You define the password column, which could have NULL values now, since we don't use passwords anymore. Does anyone have a working example of authentication using client certificates and authorization using a realm backed with a DataSource? Try doing some online searching for the type of errors you got. Here's what pops up in my quick google search: http://stackoverflow.com/questions/5086457/setting-up-client-cert-authentication-with-roles-on-tomcat-6-0 Here's another interesting article that tackles the old version of Tomcat, but the ideas are very similar. Here's a link: http://stackoverflow.com/questions/163113/can-client-cert-auth-method-be-used-with-a-jdbc-realm-within-tomcat Summary: User Names The user name column should contain the certificate subject's distinguished name, as a character string. Unfortunately, the method Tomcat uses to obtain this string produces an implementation-dependent result, so it's possible if you were to switch to a new security provider or even just upgrade your Java runtime, you might need to map your user names to a new form. You'll have to test your deployment to find out what format is used. Specifically, getName() is called on the Principal returned by X509Certificate.getSubjectDN() to obtain a String, which is used as the user name. If you read the documentation, you'll find that this is no longer the best approach. Authentication The simplest set up would be to load your trust anchors into Tomcat's trust store, which is configured in the server.xml file. With this setup, any client certificate chain that is root in one of your trusted CAs will be considered authenticated, and rightly so—authentication means that an identity is known, and is distinct from authorization, which determines what that identity is allowed to do. Authorization Since anyone with a signed certificate will be authenticated, you need to set up roles in order to protect private resources in your application. This is done by setting up security constraints, associated with roles, in your web.xml file. Then, in your database, populate the roles table to grant trusted users with extra roles. The relationship between the user table and the roles table works exactly as it would with FORM-based authorization, and should be utilized to grant appropriate permissions to users that you trust. A Note on Passwords The JDBCRealm will create a new Principal, which does carry a password, but unless your application downcasts this Principal to the Tomcat-specific implementation (GenericPrincipal), this property won't be visible to you, and it doesn't really matter what you put in that column. I recommend NULL. In other words, when using JDBCRealm with client-auth, the password field is ignored. This GenericPrincipal has a method to access an underlying principal, but unfortunately, the Principal from the certificate is not passed along; the JDBCRealm will set it to null; the only useful method in this scenario might be getName() (returning the subject DN is some possibly non-standard form). Table Structure and Content Use exactly the same table structure you would for a FORM-based JDBCRealm (or DatasourceRealm). The only difference will be in the content. The user name will be a text representation of the subject distinguished name, and the password will be NULL or some dummy value. I don't know how much of it is still relevant in Tomcat7/Tomcat8. By the way, what platform, what JVM and what version of Tomcat do you run? Hope that helps! Cheers! Neven
Re: Switching basic auth to client-cert with realms - how?
On 13 Mar 2015, at 10:34 PM, Neven Cvetkovic neven.cvetko...@gmail.com wrote: What doesn’t seem to fit is the realm definition - specifying userCredCol is marked as mandatory, but this is obviously not present with a client certificate. What do you specify in this field? You define the password column, which could have NULL values now, since we don't use passwords anymore. I don’t follow, do you mean I shouldn’t define the password column? Here's another interesting article that tackles the old version of Tomcat, but the ideas are very similar. Here's a link: http://stackoverflow.com/questions/163113/can-client-cert-auth-method-be-used-with-a-jdbc-realm-within-tomcat I’ve already found all of these, and have trawled through them to no avail. It appears all the information is stale. I am currently stuck on two specific areas: - None of the debug logging seems to work any more in any kind of predictable fashion, as detailed in my other message. - Turning on SQL statement logging in postgres shows that at no point is any SQL statement executed against the database. If I had some kind of meaningful error that accompanied the 403 it would be a huge help. Is anyone able to confirm where I might place a breakpoint to step through the tomcat code? Regards, Graham — - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Switching basic auth to client-cert with realms - how?
Hi all, I have a basic authentication setup that works great as below. login-config auth-methodBASIC/auth-method realm-namePatricia/realm-name /login-config !-- Security roles referenced by this web application -- security-role role-nameadministrator/role-name /security-role security-role role-nameunderwriter/role-name /security-role security-role role-nameaccountant/role-name /security-role security-role role-namebroker/role-name /security-role security-role role-namefeeds/role-name /security-role It is backed up with a realm like this: Realm className=“org.apache.catalina.realm.DataSourceRealm [snip] userTable=person userNameCol=mail userCredCol=user_password userRoleTable=company_person roleNameCol=serial / I need to switch basic authentication to client certificates, as provided by Apache httpd and proxied in with AJP. The username is provided by Apache httpd in REMOTE_USER. In theory, changing the auth-method to CLIENT-CERT should do the trick, but I just get forbidden. What doesn’t seem to fit is the realm definition - specifying userCredCol is marked as mandatory, but this is obviously not present with a client certificate. What do you specify in this field? Does anyone have a working example of authentication using client certificates and authorization using a realm backed with a DataSource? Regards, Graham — - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Switching basic auth to client-cert with realms - how?
Graham, On Fri, Mar 13, 2015 at 4:49 PM, Graham Leggett minf...@sharp.fm wrote: On 13 Mar 2015, at 10:34 PM, Neven Cvetkovic neven.cvetko...@gmail.com wrote: What doesn’t seem to fit is the realm definition - specifying userCredCol is marked as mandatory, but this is obviously not present with a client certificate. What do you specify in this field? You define the password column, which could have NULL values now, since we don't use passwords anymore. I don’t follow, do you mean I shouldn’t define the password column? According to my understanding - password field will be irrelevant. Since we use certificates to authenticate, not username/password combo. Thus, keep the field as is. Here's another interesting article that tackles the old version of Tomcat, but the ideas are very similar. Here's a link: http://stackoverflow.com/questions/163113/can-client-cert-auth-method-be-used-with-a-jdbc-realm-within-tomcat I’ve already found all of these, and have trawled through them to no avail. It appears all the information is stale. Yes, indeed - most of the info on these pages is very stale. Once we resolve it, we should add a nice article about this, and add to Tomcat Wiki :))) I am currently stuck on two specific areas: - None of the debug logging seems to work any more in any kind of predictable fashion, as detailed in my other message. From your other log files (your last email in the other thread) - it seems your pages are not secured at all, e.g. FINE: Not subject to any constraint Do you have security-constraint defined in your web.xml? - Turning on SQL statement logging in postgres shows that at no point is any SQL statement executed against the database. Well, we are not hitting the database yet, as secured page was not hit yet - just unsecured / - judging from your provided log files. That's why I would first make sure the logging does work properly with the other login method (BASIC/FORM), just to make sure you can see stuff being logged. Then you can switch to new CLIENT-CERT, and troubleshoot the problem. If I had some kind of meaningful error that accompanied the 403 it would be a huge help. Is anyone able to confirm where I might place a breakpoint to step through the tomcat code? I would try constructors on RealmBase, AuthenticatorBase base classes or their derived subclasses, e.g. BasicAuthenticator, SSLAuthenticator, DataSourceRealm. Try also - the authenticate() method on the DataSourceRealm ... that's probably going to be called at some point :)) Hope that helps! Cheers! Neven