Používáte-li pro správu přístupu k vaší webové aplikaci framework Acegi, možná se vám bude hodit zaznamenávat uživatelské přístupy (platné loginy) někam do databáze. Zde je jeden ze způsobů jak se s tímto problémem vypořádat. Následující přiklad používá Hibernate a databázi Oracle.
Nejdříve si připravím vlastní metodu pro zápis do databáze v DAO. Umístím ji do třídy cz.mujpackage.dao.UserDao, která rozšiřuje org.springframework.orm.hibernate3.support.HibernateDaoSupport a poskytuje metody pro správu uživatelů, rolí, apod. Pro zvýšení výkonu použiji v Hibernate SQLQuery namísto vytváření instance třídy modelu a jejího ukládání pomocí metody save(...).
/**
* Adds log entry to table AUTH_LOG (Oracle database form - pk_sequence has to be configured)
* @param aName username
* @param aRemoteAddress remote address of request
*/
public void logAuthenticationSuccess(final String aName, final String aRemoteAddress) {
final HibernateCallback callback = new HibernateCallback() {
public Object doInHibernate(final Session session) throws HibernateException {
return session
.createSQLQuery("insert into AUTH_LOG (id, datum, user, address)" +
" values (pk_sequence.nextval, sysdate, :user, :address)")
.setParameter("user", aName)
.setParameter("address", aRemoteAddress)
.executeUpdate();
}
};
getHibernateTemplate().execute(callback);
}
Nyní přijde hlavní část a to zachycení události, která je vyvolána při úspěšném přihlášení uživatele do systému. Vytvořím tedy implementaci interfejsu org.springframework.context.ApplicationListener a budu obsluhovat události typu InteractiveAuthenticationSuccessEvent.
package cz.mujpackage.acegi;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.util.Assert;
import cz.mujpackage.dao.UserDao;
/**
* Logs the successful authentication to database table
* @author Josef Cacek
*/
public class MyAuthListener implements ApplicationListener, InitializingBean {
protected final Log log = LogFactory.getLog(getClass());
private UserDao userDao;
/**
* Writes entry to AUTH_LOG table when InteractiveAuthenticationSuccessEvent comes
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof InteractiveAuthenticationSuccessEvent) {
final Authentication tmpAuth = SecurityContextHolder.getContext().getAuthentication();
log.debug("InteractiveAuthenticationSuccessEvent: " + tmpAuth.getName());
if (tmpAuth.getDetails() instanceof WebAuthenticationDetails) {
final WebAuthenticationDetails webDetails =
(WebAuthenticationDetails) tmpAuth.getDetails();
userDao.logAuthenticationSuccess(tmpAuth.getName(),webDetails.getRemoteAddress());
} else {
log.warn("Authentication.getDetails() not instance of WebAuthenticationDetails: "
+ tmpAuth.getDetails());
}
}
}
/**
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
Assert.notNull(userDao);
}
/**
* @return the userDao
*/
public UserDao getUserDao() {
return userDao;
}
/**
* @param userDao the userDao to set
*/
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
Teď už zbývá pouze nakonfigurovat beanu v applicationContext.xml a je hotovo:
<bean id="myAuthListener" class="cz.mujpackage.acegi.MyAuthListener">
<property name="userDao" ref="userDao"/>
</bean>
A jak by řekl Forrest Gump
....a to je asi tak vše, co vím o krevetách
Komentáře