我有一个令人讨厌的错误,我很久都无法解决。我最近介绍了基于容器的安全性并尝试实现它。我已将域配置如下:
<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
答案 0 :(得分:1)
如果userRoleTable
也必须设置roleNameCol
和allRolesMode="authOnly"
属性。如果没有它们,SQL查询将包含字符串null
(正如您在异常消息中看到的那样)。 userRoleTable
的值可以与userTable
的值相同,roleNameCol
也可以与userNameCol
相同。
一个简单的解决方法是创建一个模拟roles
表的SQL视图:
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兆字节。我同意这不是一个美丽的解决方案,但现在并不是无法容忍的。)
答案 1 :(得分:0)
我Tomcat 7.0.27.0
与JDK 1.6
我只使用tomcat进行身份验证和not for authorization
以下是设置
context.xml
<Realm className="org.apache.catalina.realm.JDBCRealm"
connectionName="login"
connectionPassword="password"
connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:authdb"
driverName="oracle.jdbc.OracleDriver"
userTable="appusers"
userNameCol="username"
userCredCol="password"
allRolesMode="authOnly"/>
的web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/modules/*</url-pattern>
<url-pattern>/index.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<!--
security-role>
<role-name>user</role-name>
security-role>
-->
我通过从web.xml&amp;
中删除<security-role>
块来实现它
将auth-contraint
的角色名称设为*
如果从auth-contraint
删除security-contraint
阻止,则不会调用Web上下文身份验证!!