title: Setting up client-cert authentication with roles on Tomcat 6.0
body: <p>I'm setting up a web application that uses client certificate authentication. For right now, I've just set up a test user account and a 'user' role to test authentication and authorization. I'm using a DataSourceRealm and a postgreSQL database configured as such:</p>
  
  <pre><code>&lt;Realm className="org.apache.catalina.realm.DataSourceRealm"
      dataSourceName="jdbc/postgres" localDataSource="true"
      userTable="users" userNameCol="username" userCredCol="password"
      userRoleTable="user_roles" roleNameCol="role" /&gt;
  
  &lt;Resource auth="Container" type="javax.sql.DataSource" name="jdbc/postgres"
      driverClassName="org.postgresql.Driver"
      url="jdbc:postgresql://localhost:5432/test"
      maxActive="100" maxIdle="30" maxWait="-1"
      username="test" password="test" /&gt;
  </code></pre>
  
  <p>When I first set up the database and application I used FORM authentication with the following configuration in web.xml:</p>
  
  <pre><code>&lt;security-constraint&gt;
      &lt;web-resource-collection&gt;
          &lt;web-resource-name&gt;Test&lt;/web-resource-name&gt;
          &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
          &lt;http-method&gt;GET&lt;/http-method&gt;
          &lt;http-method&gt;POST&lt;/http-method&gt;
      &lt;/web-resource-collection&gt;
  
      &lt;auth-constraint&gt;
          &lt;role-name&gt;user&lt;/role-name&gt;
      &lt;/auth-constraint&gt;
  
      &lt;user-data-constraint&gt;
          &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
      &lt;/user-data-constraint&gt;
  &lt;/security-constraint&gt;
  
  &lt;login-config&gt;
      &lt;auth-method&gt;FORM&lt;/auth-method&gt;
      &lt;form-login-config&gt;
          &lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;
          &lt;form-error-page&gt;/login-failed.jsp&lt;/form-error-page&gt;
      &lt;/form-login-config&gt;
  &lt;/login-config&gt;
  </code></pre>
  
  <p>The database contained the user: testuser and assigned the role: user. Login with FORM authentication worked as expected.</p>
  
  <p>I then changed the FORM authentication method to CLIENT-CERT and set up the necessary certificates, CA, etc. The connector in server.xml is configured like this:</p>
  
  <pre><code>   &lt;Connector SSLEnabled="true" clientAuth="true"
      maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https"
      keystoreFile="C:\Workspace\Test\keystore.jks"
      keystorePass="changeit"
      truststoreFile="C:\Workspace\Test\truststore.jks"
      truststorePass="changeit"
      secure="true" sslProtocol="TLS"/&gt;
  </code></pre>
  
  <p>The user is identified in the database as "CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"</p>
  
  <p>If I leave the auth-constraint specifying the "user" role I get a 403 permission denied error accessing any page. It looks like authentication succeeds but it cannot determine the user's role from the database. If I comment out the auth-constraint, authentication succeeds and I can access the protected page.</p>
  
  <p>It looks like it cannot look up the user's role in the database though the only thing in the db I changed was how the username is represented. After authentication the following code:</p>
  
  <pre><code>X500Principal p = certs[0].getSubjectX500Principal();
  out.println (p.getName());
  </code></pre>
  
  <p>produces "CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU" which is the value stored in the username column in the database which is also mapped to the 'user' role in the user_roles table.</p>
  
  <pre><code>test=&gt; select * from users;
                           username                          | password
  -----------------------------------------------------------+----------
   CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU |
  (1 row)
  
  test=&gt; select * from user_roles;
                           username                          | role
  -----------------------------------------------------------+------
   CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU | user
  (1 row)
  </code></pre>
  
  <p>What else should I be doing to be able to lookup the user roles? From everything I've seen so far it looks like this should work. Thanks for any help.</p>