Search code examples
tomcatjettyjdbcrealm

JDBC Realm authentication doesn't detect password changes immediately


I'm using JdbcRealm with FORM based authentication for my web application, It is created using JSF. I created a web page for user management. The problem is when a user change their password jdbcRealm doesn't reflect the changes immediately and it redirect to the error page.

I'm using for development the Jetty plugin with the following configuration:

web.xml

  <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>RealmName</realm-name>
          <form-login-config> 
             <form-login-page>/login.xhtml</form-login-page> 
             <form-error-page>/access-denied.xhtml</form-error-page> 
         </form-login-config> 
    </login-config>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>secured</web-resource-name>
            <description/>
            <url-pattern>/views/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>USER</role-name>
            <role-name>ADMINISTRATOR</role-name>
        </auth-constraint>
    </security-constraint> 

pom.xml

<plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.3.7.RC1</version>
                <configuration>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                    <webApp>
                        <contextPath>/ROOT</contextPath>
                    </webApp>
                    <dumpOnStart>true</dumpOnStart>
                    <loginServices>
                        <loginService implementation="org.eclipse.jetty.security.JDBCLoginService">
                            <name>RealmName</name>
                            <config>${project.basedir}/src/main/resources/realm.properties</config>
                        </loginService>
                    </loginServices>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.38</version>
                    </dependency>
                    <dependency>
                        <groupId>c3p0</groupId>
                        <artifactId>c3p0</artifactId>
                        <version>0.9.1.2</version>
                    </dependency>
                </dependencies>
            </plugin>

realm.properties

jdbcdriver = com.mysql.jdbc.Driver
url = urlOfMyDatabase
username = myUser
password = myPassword

usertable = table
usertablekey = id_user
usertableuserfield = username
usertablepasswordfield = password

roletable = role
roletablekey = id_role
roletablerolefield = name

userroletable = user
userroletableuserkey = id_user
userroletablerolekey = role_id
cachetime = 300

I suppose that it is because the cache time, but how can I maintain the cache and refresh it when I execute a user modification?.

The configuration below is for my developer environment, for production, I'm using a Tomcat with the following configuration:

<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="com.mysql.jdbc.Driver" localDataSource="true" connectionURL="urlOfMyDatabase" connectionName="myUser" connectionPassword="myPassword" userTable="user_view" userNameCol="username" userCredCol="password" userRoleTable="user_view" roleNameCol="role"/>

I hope you can help me :)


Solution

  • I guess that the password change doesn't get picked up for 5 minutes? Check your realm.properties on how I guessed this. Hint: Look towards the end of that file, or ctrl+f 300 on this page.

    You probably don't need any cache at all: The probability of many users logging in again after 5 minutes (thus making use of the cache) is probably close to zero. Thus this cache will only cost you memory while not gaining anything from it. If a simple lookup of a single record slows down your application or database, you've got another problem. Just get rid of it.

    Having the cache there without any measurement that it helps is called premature optimization. And you'll find elsewhere that premature optimization is the root of all evil.