Tomcat从JDBCRealm切换到DataSourceRealm后认证失效问题排查
问题描述
将运行正常的Web应用从Tomcat 9.0升级到Tomcat 10.1,原使用的JDBCRealm已被弃用,按照官方建议改用DataSourceRealm,修改context.xml和server.xml后认证功能失效,日志仅输出:
25-Jan-2023 10:13:50.699 SEVERE [http-nio-8080-exec-23] org.apache.catalina.realm.DataSourceRealm.open Exception performing authentication
现有配置
context.xml 内容
<Context path="/TASSU"> <Realm className="org.apache.catalina.realm.DataSourceRealm" connectionName="root" connectionPassword="sesame" connectionURL="jdbc:mysql://localhost:3306/login_details" debug="99" driverName="com.mysql.jdbc.Driver" roleNameCol="Rolename" userCredCol="Password" userNameCol="Username" userRoleTable="userrole" userTable="userpass"/> </Context>
server.xml 中的Realm配置
<Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Realm className="org.apache.catalina.realm.DataSourceRealm" connectionName="root" connectionPassword="sesame" connectionURL="jdbc:mysql://localhost:3306/login_details" debug="99" driverName="com.mysql.jdbc.Driver" roleNameCol="Rolename" userCredCol="Password" userNameCol="Username" userRoleTable="userrole" userTable="userpass"/> </Realm>
问题排查与建议
重复配置冲突:
server.xml的LockOutRealm内已配置DataSourceRealm,同时context.xml又重复配置该Realm,Tomcat的Realm按层级加载,重复配置会导致认证逻辑混乱。建议保留server.xml中的配置(搭配LockOutRealm可防止暴力破解),删除context.xml内的Realm节点。JDBC驱动类错误:若使用MySQL 8.0及以上版本驱动,正确驱动类应为
com.mysql.cj.jdbc.Driver,当前配置的com.mysql.jdbc.Driver是旧版类名,在新版驱动中已被移除,会导致数据库连接失败。需根据驱动版本调整驱动类参数。DataSourceRealm配置方式不规范:当前配置沿用了JDBCRealm直接配置连接参数的方式,但DataSourceRealm标准用法是先配置数据源资源,再通过
dataSourceName引用。正确配置示例:- 在
server.xml的GlobalNamingResources节点下添加数据源:<Resource name="jdbc/LoginDB" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="root" password="sesame" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/login_details?useSSL=false&serverTimezone=UTC"/> - 修改
LockOutRealm内的DataSourceRealm配置,引用上述数据源:<Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/LoginDB" userTable="userpass" userNameCol="Username" userCredCol="Password" userRoleTable="userrole" roleNameCol="Rolename"/>
- 在
日志信息不足:当前日志仅提示认证异常,无具体栈信息。需调整Tomcat日志配置,将
org.apache.catalina.realm的日志级别设为DEBUG或FINE,以便查看具体异常原因(如驱动缺失、数据库连接失败、SQL查询错误等)。表字段匹配验证:确认数据库中
userpass表的用户名字段为Username、密码字段为Password,userrole表的角色字段为Rolename,表名与字段名的大小写需与数据库实际结构一致(MySQL默认不区分大小写,但部分场景下可能存在差异)。
内容的提问来源于stack exchange,提问作者Luke_Skywalker007

