【问题标题】:Authentication without authorization on Tomcat 7在Tomcat 7上未经授权的身份验证
【发布时间】:2013-01-17 19:36:44
【问题描述】:

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

<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

【问题讨论】:

    标签: sql authentication tomcat jdbcrealm


    【解决方案1】:

    您也必须设置userRoleTableroleNameCol 属性以防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.xmlsn-ps:

    <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 表中的新属性与 100 万 user\0 字符串将仅花费大约 5 兆字节。我同意这不是一个漂亮的解决方案,但它不是现在大得不能容忍。)

    【讨论】:

    • 谢谢。毕竟,我试图说服 db admin 添加此用户角色列,但如果我的协商不起作用,我会尝试你的方法。然而,tomcat 有这样的限制真的很愚蠢:/ 我的意思是 - 有时您可能对数据库构建没有任何影响,然后您就搞砸了:/ 简单的功能 = 大问题...
    • “和解决方案”无需任何数据库架构修改即可工作,还有一些其他方法:编写自定义JDBCRealm(Tomcat 是开源的,因此您可以修改现有的),实现自定义Valve 将角色添加到用户的主体。所以,这不是不可能的,但需要一些工作:)
    【解决方案2】:

    我有Tomcat 7.0.27.0JDK 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 中删除 &lt;security-role&gt; 块 &
    让它工作了 将auth-contraint 与角色名称作为*

    如果您从 security-contraint 中删除 auth-contraint 块,则不会调用 Web 上下文身份验证本身!!

    【讨论】:

      猜你喜欢
      • 2016-04-15
      • 2021-07-17
      • 2018-06-13
      • 2018-07-09
      • 2018-10-16
      • 1970-01-01
      • 2016-08-15
      • 1970-01-01
      相关资源
      最近更新 更多