dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #04696
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 1567: Impl logging of authentication failures through an ApplicationListener. Moved logging of authenti...
------------------------------------------------------------
revno: 1567
committer: Lars Helge Oeverland <larshelge@xxxxxxxxx>
branch nick: trunk
timestamp: Sat 2010-03-06 18:02:42 +0100
message:
Impl logging of authentication failures through an ApplicationListener. Moved logging of authentication successes to the same listener. Spring Security emits handy ApplicationEvents for authentication success and failure which are now used for detection. Minor re-factor, renamed FailedLogin to LoginFailure.
added:
dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/listener/
dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/listener/AuthenticationListener.java
renamed:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/FailedLogin.java => dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/LoginFailure.java
dhis-2/dhis-services/dhis-service-administration/src/main/resources/org/hisp/dhis/useraudit/hibernate/FailedLogin.hbm.xml => dhis-2/dhis-services/dhis-service-administration/src/main/resources/org/hisp/dhis/useraudit/hibernate/LoginFailure.hbm.xml
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditService.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditStore.java
dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/DefaultUserAuditService.java
dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/hibernate/HibernateUserAuditStore.java
dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/useraudit/UserAuditStoreTest.java
dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/LoggedInAction.java
dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml
dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/LoginFailure.java
dhis-2/dhis-services/dhis-service-administration/src/main/resources/org/hisp/dhis/useraudit/hibernate/LoginFailure.hbm.xml
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription.
=== renamed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/FailedLogin.java' => 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/LoginFailure.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/FailedLogin.java 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/LoginFailure.java 2010-03-06 17:02:42 +0000
@@ -2,7 +2,7 @@
import java.util.Date;
-public class FailedLogin
+public class LoginFailure
{
private int id;
@@ -10,11 +10,11 @@
private Date date;
- public FailedLogin()
+ public LoginFailure()
{
}
- public FailedLogin( String username, Date date )
+ public LoginFailure( String username, Date date )
{
this.username = username;
this.date = date;
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditService.java 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditService.java 2010-03-06 17:02:42 +0000
@@ -5,9 +5,9 @@
final int TIMEFRAME_NUMBER_OF_HOURS = 1;
final int MAX_NUMBER_OF_ATTEMPTS = 3;
- void registerLogin( String username );
+ void registerLoginSuccess( String username );
void registerLogout( String username );
- void registerLoginFailed( String username );
+ void registerLoginFailure( String username );
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditStore.java 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/useraudit/UserAuditStore.java 2010-03-06 17:02:42 +0000
@@ -7,9 +7,11 @@
{
final String ID = UserAuditStore.class.getName();
- void saveFailedLogin( FailedLogin login );
-
- Collection<FailedLogin> getAllFailedLogins();
-
- int getFailedLogins( String username, Date date );
+ void saveLoginFailure( LoginFailure login );
+
+ Collection<LoginFailure> getAllLoginFailures();
+
+ void deleteLoginFailures( String username );
+
+ int getLoginFailures( String username, Date date );
}
=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/DefaultUserAuditService.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/DefaultUserAuditService.java 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/DefaultUserAuditService.java 2010-03-06 17:02:42 +0000
@@ -5,6 +5,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.transaction.annotation.Transactional;
public class DefaultUserAuditService
implements UserAuditService
@@ -18,9 +19,9 @@
this.userAuditStore = userAuditStore;
}
- public void registerLogin( String username )
+ public void registerLoginSuccess( String username )
{
- log.info( "User login: '" + username + "'" );
+ log.info( "User login success: '" + username + "'" );
}
public void registerLogout( String username )
@@ -28,17 +29,20 @@
log.info( "User logout: '" + username + "'" );
}
- public void registerLoginFailed( String username )
+ @Transactional
+ public void registerLoginFailure( String username )
{
- log.info( "User login failed: '" + username + "'" );
-
- userAuditStore.saveFailedLogin( new FailedLogin( username, new Date() ) );
-
- int no = userAuditStore.getFailedLogins( username, getDate() );
-
- if ( no > MAX_NUMBER_OF_ATTEMPTS )
+ log.info( "User login failure: '" + username + "'" );
+
+ userAuditStore.saveLoginFailure( new LoginFailure( username, new Date() ) );
+
+ int no = userAuditStore.getLoginFailures( username, getDate() );
+
+ if ( no >= MAX_NUMBER_OF_ATTEMPTS )
{
log.info( "Max number of login attempts exceeded: '" + username + "'" );
+
+ userAuditStore.deleteLoginFailures( username );
}
}
=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/hibernate/HibernateUserAuditStore.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/hibernate/HibernateUserAuditStore.java 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/useraudit/hibernate/HibernateUserAuditStore.java 2010-03-06 17:02:42 +0000
@@ -5,7 +5,7 @@
import org.hibernate.Session;
import org.hibernate.SessionFactory;
-import org.hisp.dhis.useraudit.FailedLogin;
+import org.hisp.dhis.useraudit.LoginFailure;
import org.hisp.dhis.useraudit.UserAuditStore;
public class HibernateUserAuditStore
@@ -18,26 +18,33 @@
this.sessionFactory = sessionFactory;
}
- public void saveFailedLogin( FailedLogin login )
+ public void saveLoginFailure( LoginFailure login )
{
sessionFactory.getCurrentSession().save( login );
}
@SuppressWarnings( "unchecked" )
- public Collection<FailedLogin> getAllFailedLogins()
+ public Collection<LoginFailure> getAllLoginFailures()
{
- return sessionFactory.getCurrentSession().createCriteria( FailedLogin.class ).list();
+ return sessionFactory.getCurrentSession().createCriteria( LoginFailure.class ).list();
}
- public int getFailedLogins( String username, Date date )
+ public void deleteLoginFailures( String username )
+ {
+ String hql = "delete from LoginFailure where username = :username";
+
+ sessionFactory.getCurrentSession().createQuery( hql ).setString( "username", username ).executeUpdate();
+ }
+
+ public int getLoginFailures( String username, Date date )
{
Session session = sessionFactory.getCurrentSession();
- String hql = "delete from FailedLogin where date < :date";
+ String hql = "delete from LoginFailure where date < :date";
session.createQuery( hql ).setDate( "date", date ).executeUpdate();
- hql = "select count(*) from FailedLogin where username = :username";
+ hql = "select count(*) from LoginFailure where username = :username";
Long no = (Long) session.createQuery( hql ).setString( "username", username ).uniqueResult();
=== renamed file 'dhis-2/dhis-services/dhis-service-administration/src/main/resources/org/hisp/dhis/useraudit/hibernate/FailedLogin.hbm.xml' => 'dhis-2/dhis-services/dhis-service-administration/src/main/resources/org/hisp/dhis/useraudit/hibernate/LoginFailure.hbm.xml'
--- dhis-2/dhis-services/dhis-service-administration/src/main/resources/org/hisp/dhis/useraudit/hibernate/FailedLogin.hbm.xml 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/resources/org/hisp/dhis/useraudit/hibernate/LoginFailure.hbm.xml 2010-03-06 17:02:42 +0000
@@ -4,8 +4,8 @@
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
- <class name="org.hisp.dhis.useraudit.FailedLogin" table="failedlogin">
- <id name="id" column="failedloginid">
+ <class name="org.hisp.dhis.useraudit.LoginFailure" table="loginfailure">
+ <id name="id" column="loginfailureid">
<generator class="native"/>
</id>
<property name="username"/>
=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/useraudit/UserAuditStoreTest.java'
--- dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/useraudit/UserAuditStoreTest.java 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/useraudit/UserAuditStoreTest.java 2010-03-06 17:02:42 +0000
@@ -19,23 +19,23 @@
@Test
public void save()
{
- userAuditStore.saveFailedLogin( new FailedLogin( "userA", getDate( 2000, 1, 3 ) ) );
- userAuditStore.saveFailedLogin( new FailedLogin( "userA", getDate( 2000, 1, 4 ) ) );
- userAuditStore.saveFailedLogin( new FailedLogin( "userB", getDate( 2000, 1, 5 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userA", getDate( 2000, 1, 3 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userA", getDate( 2000, 1, 4 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userB", getDate( 2000, 1, 5 ) ) );
- assertNotNull( userAuditStore.getAllFailedLogins() );
- assertEquals( 3, userAuditStore.getAllFailedLogins().size() );
+ assertNotNull( userAuditStore.getAllLoginFailures() );
+ assertEquals( 3, userAuditStore.getAllLoginFailures().size() );
}
@Test
public void get()
{
- userAuditStore.saveFailedLogin( new FailedLogin( "userA", getDate( 2000, 1, 3 ) ) );
- userAuditStore.saveFailedLogin( new FailedLogin( "userA", getDate( 2000, 1, 4 ) ) );
- userAuditStore.saveFailedLogin( new FailedLogin( "userA", getDate( 2000, 1, 5 ) ) );
- userAuditStore.saveFailedLogin( new FailedLogin( "userA", getDate( 2000, 1, 6 ) ) );
- userAuditStore.saveFailedLogin( new FailedLogin( "userB", getDate( 2000, 1, 7 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userA", getDate( 2000, 1, 3 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userA", getDate( 2000, 1, 4 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userA", getDate( 2000, 1, 5 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userA", getDate( 2000, 1, 6 ) ) );
+ userAuditStore.saveLoginFailure( new LoginFailure( "userB", getDate( 2000, 1, 7 ) ) );
- assertEquals( 3, userAuditStore.getFailedLogins( "userA", getDate( 2000, 1, 4 ) ) );
+ assertEquals( 3, userAuditStore.getLoginFailures( "userA", getDate( 2000, 1, 4 ) ) );
}
}
=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/LoggedInAction.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/LoggedInAction.java 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/LoggedInAction.java 2010-03-06 17:02:42 +0000
@@ -33,8 +33,7 @@
import org.hisp.dhis.oust.manager.SelectionTreeManager;
import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
import org.hisp.dhis.user.CurrentUserService;
-import org.hisp.dhis.useraudit.UserAuditService;
-import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;
+import org.hisp.dhis.user.User;
import com.opensymphony.xwork2.Action;
@@ -70,13 +69,6 @@
this.currentUserService = currentUserService;
}
- private UserAuditService userAuditService;
-
- public void setUserAuditService( UserAuditService userAuditService )
- {
- this.userAuditService = userAuditService;
- }
-
// -------------------------------------------------------------------------
// Action implementation
// -------------------------------------------------------------------------
@@ -84,21 +76,15 @@
public String execute()
throws Exception
{
- String username = currentUserService.getCurrentUsername();
+ User user = currentUserService.getCurrentUser();
- if ( username != null )
+ if ( user != null )
{
// -----------------------------------------------------------------
- // Register login
- // -----------------------------------------------------------------
-
- userAuditService.registerLogin( username );
-
- // -----------------------------------------------------------------
// Initialize ouwt and selection tree
// -----------------------------------------------------------------
- Collection<OrganisationUnit> orgUnits = currentUserService.getCurrentUser().getOrganisationUnits();
+ Collection<OrganisationUnit> orgUnits = user.getOrganisationUnits();
if ( orgUnits.size() > 0 )
{
=== added directory 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/listener'
=== added file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/listener/AuthenticationListener.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/listener/AuthenticationListener.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/listener/AuthenticationListener.java 2010-03-06 17:02:42 +0000
@@ -0,0 +1,35 @@
+package org.hisp.dhis.security.listener;
+
+import org.hisp.dhis.useraudit.UserAuditService;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.security.event.authentication.AbstractAuthenticationFailureEvent;
+import org.springframework.security.event.authentication.AuthenticationSuccessEvent;
+import org.springframework.security.userdetails.UserDetails;
+
+public class AuthenticationListener
+ implements ApplicationListener
+{
+ private UserAuditService userAuditService;
+
+ public void setUserAuditService( UserAuditService userAuditService )
+ {
+ this.userAuditService = userAuditService;
+ }
+
+ public void onApplicationEvent( ApplicationEvent applicationEvent )
+ {
+ if ( applicationEvent != null && applicationEvent instanceof AuthenticationSuccessEvent )
+ {
+ AuthenticationSuccessEvent event = (AuthenticationSuccessEvent) applicationEvent;
+
+ userAuditService.registerLoginSuccess( ((UserDetails) event.getAuthentication().getPrincipal()).getUsername() );
+ }
+ else if ( applicationEvent != null && applicationEvent instanceof AbstractAuthenticationFailureEvent )
+ {
+ AbstractAuthenticationFailureEvent event = (AbstractAuthenticationFailureEvent) applicationEvent;
+
+ userAuditService.registerLoginFailure( (String) event.getAuthentication().getPrincipal() );
+ }
+ }
+}
=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml 2010-03-06 16:00:25 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml 2010-03-06 17:02:42 +0000
@@ -268,8 +268,6 @@
ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
<property name="selectionTreeManager"
ref="org.hisp.dhis.oust.manager.SelectionTreeManager" />
- <property name="userAuditService"
- ref="org.hisp.dhis.useraudit.UserAuditService" />
</bean>
<!-- Security : Filter -->
@@ -319,6 +317,12 @@
<property name="loginPageUrl" value="/dhis-web-commons/security/login.html" />
</bean>
+ <!-- Security : Listener -->
+
+ <bean id="authenticationListener" class="org.hisp.dhis.security.listener.AuthenticationListener">
+ <property name="userAuditService" ref="org.hisp.dhis.useraudit.UserAuditService" />
+ </bean>
+
<!-- Security : AccessProvider -->
<bean id="databaseAutomaticAccessProvider" class="org.hisp.dhis.security.DatabaseAutomaticAccessProvider">