org.openid4java.consumer.JdbcNonceVerifier Maven / Gradle / Ivy
The newest version!
package org.openid4java.consumer ;
import java.util.Date ;
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;
import org.springframework.dao.DataIntegrityViolationException ;
import org.springframework.jdbc.core.JdbcTemplate ;
import org.springframework.jdbc.core.support.JdbcDaoSupport ;
/**
*
* JDBC implementation of a NonceVerifier.
*
* The JdbcNonceVerifier requires a a javax.sql.DataSource to be configured
* and passed in to it with the setDataSource setter method. The table name
* also needs to be specified, either through the constructor, or through the
* setTableName setter.
*
*
* Since the nonces are constructed on the web server and not on the shared
* database server, they may accidentally collide. Also, if the machines
* clocks are out of sync, the nonces from the machine that is behind may be
* removed prematurely from the database by the other machine.
*
*
* The specified table must have the following structure:
*
* - opurl : string
* - nonce : string
* - date : date
* - primary key : opurl, nonce
*
*
*
* @author Andrew Evenson, Graff Haley
* @created May 19, 2008
*/
public class JdbcNonceVerifier
extends JdbcDaoSupport
implements NonceVerifier
{
private static Log _log = LogFactory.getLog ( JdbcNonceVerifier.class ) ;
private NonceVerifier _verifier ;
private String _tableName ;
private String _deleteSQL ;
private String _insertSQL ;
public JdbcNonceVerifier ( int maxAge )
{
_verifier = new GenericNonceVerifier ( maxAge ) ;
}
public JdbcNonceVerifier ( int maxAge, String tableName )
{
this ( maxAge ) ;
setTableName ( tableName ) ;
}
public int getMaxAge ( )
{
return _verifier.getMaxAge ( ) ;
}
public void setMaxAge(int ageSeconds)
{
_verifier.setMaxAge(ageSeconds);
}
public int seen ( String opUrl, String nonce )
{
return _verifier.seen ( opUrl, nonce ) ;
}
public String getTableName ( )
{
return _tableName ;
}
public void setTableName ( String tableName )
{
this._tableName = tableName ;
this._deleteSQL = "DELETE FROM " + tableName + " WHERE date>?" ;
this._insertSQL = "INSERT INTO " + tableName + " (opurl, nonce, date) VALUES (?,?,?)" ;
}
private class GenericNonceVerifier
extends AbstractNonceVerifier
{
public GenericNonceVerifier ( int maxAge )
{
super ( maxAge ) ;
}
/**
*
* Implementation of the abstract nonce verifier. Uses the primary key
* integrity constraint to evaluate nonces. This prevents a gap
* between check and insert. Also, triggers the cleanup of old nonces.
*
* @param now
* @param opUrl
* @param nonce
* @return
*/
protected int seen ( Date now, String opUrl, String nonce )
{
cleanupAged ( ) ;
JdbcTemplate jdbcTemplate = getJdbcTemplate ( ) ;
try
{
jdbcTemplate.update ( _insertSQL, new Object[]
{ opUrl, nonce, now } ) ;
return OK ;
}
catch ( DataIntegrityViolationException e )
{
_log.warn ( "Nonce already seen. Possible replay attack!" ) ;
}
catch ( Exception e )
{
_log.error ( "Problem executing database method", e ) ;
}
return SEEN ;
}
private void cleanupAged ( )
{
try
{
Date boundary = new Date ( System.currentTimeMillis ( ) - _maxAgeSeconds * 1000 ) ;
JdbcTemplate jdbcTemplate = getJdbcTemplate ( ) ;
int cnt = jdbcTemplate.update ( _deleteSQL, new Object[]
{ boundary } ) ;
if ( _log.isDebugEnabled ( ) ) _log.debug ( "Client nonce cleanup removed " + cnt + " entries" ) ;
}
catch ( Exception e )
{
_log.error ( "Error cleaning up client nonces from table: " + _tableName, e ) ;
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy