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