开发者

Authentication without authorization on Tomcat 7

开发者 https://www.devze.com 2023-04-12 23:59 出处:网络
I have an annoying error which I can\'t solve for quite a while. I recently was introduced to container-based security and try to implement it. I have configure the realm as following:

I have an annoying error which I can't solve for quite a while. I recently was introduced to container-based security and try to implement it. I have configure the realm as following:

<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>

Unfortunately I can't login with this. The log error messages are:

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.cata开发者_C百科lina.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)

Please notice the '' around the user name... Is this correct?

As you see I also use allRolesMode="authOnly", because I don't need this functionality and moreover the database doesn't have and won't ever have an additional column for user roles (it is quite pointless if won't use it than every user will have the same value in this column - big waste of recourses.).

The server is Tomcat 7.0.19


You have to set the userRoleTable and roleNameCol properties in case of allRolesMode="authOnly" too. Without them the SQL query will contain the String null (as you can see in the message of the exception). The value of userRoleTable could be the same as the value of userTable, and roleNameCol also could be same as userNameCol.

A simple workaround is creating an SQL view which emulates the roles table:

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

And a solution:

<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"
/> 

(Surprisingly it works without any allRolesMode.)

The required web.xml snippets:

<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>

(Note: Lets say you have 1 million users, a new attribute in the users table with one million user\0 string would cost only around 5 megabytes. I agree with that this is not a beautiful solution but it's not intolerable big nowadays.)


I have Tomcat 7.0.27.0 with JDK 1.6

I am using tomcat only for Authentication and not for authorization

Following is the setup

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>
-->

I got it working by removing <security-role> block from web.xml &
putting auth-contraint with role-name as *

If you remove auth-contraint block from security-contraint then web context authentication itself will not be invoked !!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号