5

我希望从 MySQL 数据库加载用户(允许登录到我的站点)。为此,我想为我的 Apache Tomcat 7 应用程序服务器设置一个 JDBCRealm。

我已经阅读了文档并使用 JNDI 资源 (jdbc/foo4) 创建了一个数据库连接。该资源有效(我已经在我的应用程序中使用它来检索数据)。似乎不起作用的是将领域与此资源联系起来。

我的配置文件如下所示:

src\main\webapp\META-INF\context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/my-webapp">
  <!-- works! -->
  <Resource name="jdbc/foo4"
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/foo4"
            username="root"
            password="root"
            maxActive="8" 
            maxIdle="4" 
            maxWait="10000"
            auth="Container"
          />
  <!-- Does not seem to work?! -->
  <Realm className="org.apache.catalina.realm.DataSourceRealm"
         dataSourceName="jdbc/foo4"
         userTable="users" 
         userNameCol="user_name" 
         userCredCol="user_pass"
         userRoleTable="user_roles" 
         roleNameCol="role_name"/>
</Context>

在我的标准部署描述符中,我输入了以下内容:

src\main\webapp\WEB-INF\web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <security-constraint>
    <display-name>General Restriction</display-name>
    <web-resource-collection>
      <web-resource-name>Entire Application</web-resource-name>
      <description>All resources in this application are protected.</description>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>admin</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>Administration Area</realm-name>
    <form-login-config>
      <form-login-page>/login.jsp</form-login-page>
      <form-error-page>/error.jsp</form-error-page>
    </form-login-config>
  </login-config>
  <security-role>
    <role-name>admin</role-name>
  </security-role>
  <resource-ref>
    <res-ref-name>jdbc/foo4</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

我使用这个 SQL 脚本创建了一个示例用户:

安全.sql

创建表用户( user_name varchar(15) not null 主键,user_pass varchar(15) not null );

创建表 user_roles ( user_name varchar(15) not null,
role_name varchar(15) not null, 主键 (user_name, role_name) );

INSERT INTO users(user_name,user_pass)VALUES('benny','test'); 插入到 user_roles(user_name,role_name)VALUES('benny','admin');

但我无法使用用户“benny”和密码“test”登录。我可以使用用户“tomcat”和密码“tomcat”登录(因为它是在 %CATALINA_HOME%\conf\tomcat-users.xml 中定义的),但我无法使用我自己的用户从我的 MySQL 数据库登录。

当然,我的 Tomcat 服务器使用的是 MySQL 驱动程序(我将“mysql-connector-java-5.1.9.jar”放入 %CATALINA_HOME%\lib)。

当我尝试登录时收到以下错误消息:

Sep 08, 2012 7:38:55 PM org.apache.catalina.realm.DataSourceRealm open
Exception performing authentication
javax.naming.NameNotFoundException: Name [jdbc/foo4] is not bound in this Context. Unable to find [jdbc].

有人看到错误吗?

4

1 回答 1

11

默认情况下,领域将始终查找全局数据源(在 Tomcat 端中配置/conf/server.xml),但是您已经定义了本地数据源(在相同的 webapp 端中配置/META-INF/context.xml),因此领域无法找到数据源。您需要将localDataSource属性设置为true.

<Realm ... localDataSource="true" />

另请参阅Tomcat 7.0 领域文档

localDataSource

当领域嵌套在 Context 元素中时,这允许领域使用为 Context 定义的 DataSource 而不是全局 DataSource。如果未指定,则默认为false:使用全局 DataSource。

于 2012-09-08T17:50:52.907 回答