sql - 在 Tomcat 7 上未经授权的身份验证

标签 sql authentication tomcat jdbcrealm

我有一个烦人的错误,很长一段时间我都无法解决。我最近了解到基于容器的安全性并尝试实现它。我已将领域配置如下:

<Realm className="org.apache.catalina.realm.JDBCRealm" 
debug="99" 
driverName="com.mysql.jdbc.Driver" 
connectionURL="jdbc:mysql://127.0.0.1:3306/identify" 
connectionName="adm" connectionPassword="pw" 
userTable="users" userNameCol="login" 
userCredCol="password" 
allRolesMode="authOnly" /> 
</Realm>

不幸的是我不能用这个登录。日志错误消息是:

SEVERE: Exception performing authentication
    java.sql.SQLException: You have an error in your SQL syntax; 
    check the manual that corresponds to your MySQL server version 
    for the right syntax to use near 'null WHERE login = 'user1'' at line 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1666)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2994)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:936)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1030)
at org.apache.catalina.realm.JDBCRealm.getRoles(JDBCRealm.java:640)
at org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:430)
at org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:355)
at org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:146)
at org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:180)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:282)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:440)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)

请注意用户名周围的“”...这是正确的吗?

如您所见,我还使用了 allRolesMode="authOnly",因为我不需要此功能,而且数据库没有也永远不会有用于用户角色的附加列(如果不使用它是毫无意义的,因为每个用户在此列中将具有相同的值 - 资源的巨大浪费。)。

服务器是Tomcat 7.0.19

最佳答案

如果是 allRolesMode="authOnly",您还必须设置 userRoleTableroleNameCol 属性。如果没有它们,SQL 查询将包含字符串 null(如您在异常消息中所见)。 userRoleTable的值可以和userTable的值一样,roleNameCol也可以和userNameCol一样.

一个简单的解决方法是创建一个模拟 roles 表的 SQL View :

CREATE VIEW roles (username, role)
AS SELECT username, 'user' FROM users;

解决方案:

<Realm className="org.apache.catalina.realm.JDBCRealm" 
    driverName="com.mysql.jdbc.Driver" 
    connectionURL="jdbc:mysql://127.0.0.1:3306/test" 
    connectionName="..." connectionPassword="..." 
    userTable="users" userNameCol="username" userCredCol="password" 
    userRoleTable="users" roleNameCol="username"
/> 

(令人惊讶的是,它可以在没有任何 allRolesMode 的情况下工作。)

所需的 web.xml 片段:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>protected zone</web-resource-name>
        <url-pattern>/prot/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>
</security-constraint>

<security-role>
     <role-name>*</role-name>
</security-role>

(注意:假设您有 100 万用户,users 表中包含一百万 user\0 字符串的新属性仅需 5 MB 左右。我同意这不是一个漂亮的解决方案,但现在也不是不能容忍的大。)

关于sql - 在 Tomcat 7 上未经授权的身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7756048/

相关文章:

java - 项目使用 Tomcat JNDI 数据源查找时如何实现 Liquibase 变更日志

sql - 如何更新记录的所有列而不必列出每一列

asp.net-mvc - asp.net mvc 中 HttpUnauthorizedResult 上的默认登录 url

java - Tomcat预言机钱包配置。如何将 oraclepki.jar 添加到类路径

angularjs - 使用 MEAN + Passport 根据用户角色更改 View

php - 非常简单的 PHP + MySql 登录表单不起作用?

tomcat - (Tomcat) 部署时备份 WAR

sql - 如何在同一个 select 语句中使用 count 和 group by

sql - 如何插入一条记录并返回主键来更新另一个表中的外键?

c# - 使用 C#(或任何其他方法)将 XML 转换为 SQL Server 表