4

For webapp testapp which has the following in its web.xml (among other things)

<security-constraint>
    <web-resource-collection>
        <web-resource-name>My JSP</web-resource-name>
        <url-pattern>*.secured</url-pattern>
        <url-pattern>/login</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>

    <auth-constraint>
        <role-name>mobileusers</role-name>
    </auth-constraint>
    <!--
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
    -->
</security-constraint>

<login-config>
    <auth-method>DIGEST</auth-method>
    <realm-name>Identity</realm-name>
</login-config>

<security-role>
    <description>
        No Description
    </description>
    <role-name>mobileusers</role-name>
</security-role>

Consider the following two Tomcat Realm configurations:

Configuration 1 - JDBC Realm:

In .../webapps/testapp/META-INF/context.xml

<Realm  className="org.apache.catalina.realm.JDBCRealm" 
        driverName="com.mysql.jdbc.Driver"
        connectionName="mysqluser"
        connectionPassword="redacted"
        connectionURL="jdbc:mysql://192.168.1.5/testdb?autoReconnectForPools=true&amp;characterEncoding=UTF-8"
        digest="MD5"
        userTable="Users" 
        userNameCol="name" 
        userCredCol="password"
        userRoleTable="Users" 
        roleNameCol="roleName"
/>

Configuration 2 - DataSource Realm:

In .../webapps/testapp/META-INF/context.xml:

<Realm  className="org.apache.catalina.realm.DataSourceRealm" 
        digest="MD5"
        userTable="Users" 
        userNameCol="name" 
        userCredCol="password"
        userRoleTable="Users" 
        roleNameCol="roleName"
        dataSourceName="jdbc/testDB"
/>

And in .../conf/context.xml:

<Resource 
    name="jdbc/testDB" 
    auth="Container" 
    type="javax.sql.DataSource" 
    removeAbandoned="true" 
    removeAbandonedTimeout="15" 
    maxActive="5" 
    maxIdle="5" 
    maxWait="7000" 
    username="mysqluser"
    password="redacted"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://192.168.1.5/testdb?autoReconnectForPools=true&amp;characterEncoding=UTF-8"
    factory="com.mycompany.util.configuration.customfactory"
    validationQuery="SELECT '1';"
    testOnBorrow="true"/>

For reasons I'm not clear on, Configuration 1 works for us, but Configuration 2 does not. Note that we use the Context.xml resource from Configuration 2 to connect to MySQL in our code all over the place, and it works great. When a tomcat Realm tries to use it, however, authentication always fails, even though it appears to be doing the same thing as Configuration 1.

Anyone have any insight as to why this might be?

Laurent.B
  • 213
  • 2
  • 14
Cody S
  • 4,744
  • 8
  • 33
  • 64
  • And I just realized...is this a better question for serverfault? I'm a Java dev, so I'm used to asking questions here, but... – Cody S Dec 05 '12 at 19:37
  • I am trying to replicate configuration 1, but unfortunately I don't have any META-INF directory. I used maven jersey-quickstart-archtype to generate project for me. What can I do to generate the directory and context.xml. Or manually where can I place this directory or create the file myself? – Kuldeep Yadav Sep 26 '16 at 11:27
  • I'm not sure. Typically, when you build a WAR file with Maven and unpack it, you'll have a META-INF directory. If you want to add stuff to your project to be included in META-INF, typically (in my experience), you create the directory `src/main/webapp/META-INF/` and then put files in there. – Cody S Sep 26 '16 at 17:20
  • I am trying to setup realm for my webapp. Please help. http://stackoverflow.com/questions/39715453/tomcat-realm-not-able-to-set-realm-for-my-web-application – Kuldeep Yadav Sep 27 '16 at 03:21

1 Answers1

10

Assuming that you have the DataSource working elsewhere (in, say, Servlets), all you have to do is add localDataSource="true" to the Realm decleration such that the Realm is:

<Realm  className="org.apache.catalina.realm.DataSourceRealm"
    localDataSource="true"
    digest="MD5"
    userTable="Users" 
    userNameCol="name" 
    userCredCol="password"
    userRoleTable="Users" 
    roleNameCol="roleName"
    dataSourceName="jdbc/testDB"
/>

At least, that's what worked for me.

To be perfectly, 100% clear, despite the name of this parameter, you do NOT need to put the DataSource inside of the Webapp's context.xml if you don't want to; the server's context XML will work just fine.

Laurent.B
  • 213
  • 2
  • 14
Cody S
  • 4,744
  • 8
  • 33
  • 64
  • 2
    Note that this is also a solution for the unhelpful JNDI error `javax.naming.NameNotFoundException: Name jdbc is not bound in this Context` when performing JAAS authentication using a DataSourceRealm. – Ben Zuill-Smith Jul 05 '13 at 22:22
  • For using tomcat 8 and above digest property wont work instead we need to include CredentialHandler tag. – laksys Apr 10 '20 at 15:16