Tomcat JDBC vs. DataSource Realm

2019-03-30 12:52发布

问题:

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?

回答1:

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.