From 399fb94c27144814ac05c482d6a965de1a4d8093 Mon Sep 17 00:00:00 2001 From: Joze RIHTARSIC <joze.RIHTARSIC@ext.ec.europa.eu> Date: Mon, 14 Mar 2022 17:19:56 +0100 Subject: [PATCH] Update idle times --- pom.xml | 2 +- .../smp/data/ui/enums/SMPPropertyEnum.java | 4 +- .../auth/SMPAuthenticationEventListener.java | 23 ++++-- .../SMPAuthenticationEventListenerTest.java | 79 +++++++++++++++++++ 4 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java diff --git a/pom.xml b/pom.xml index f91734252..756d58f1f 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- Only selected modules are deployed --> <maven.deploy.skip>true</maven.deploy.skip> - <edelivery.ssl-auth.version>1.10-SNAPSHOT</edelivery.ssl-auth.version> + <edelivery.ssl-auth.version>1.9</edelivery.ssl-auth.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <ant-commons-net.version>1.6.5</ant-commons-net.version> diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java index e7599fa6f..5b74e6c29 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java @@ -65,8 +65,8 @@ public enum SMPPropertyEnum { UI_COOKIE_SESSION_SITE("smp.ui.session.strict","Lax","Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks. Possible values are: Strict, None, Lax. (Cookies with SameSite=None require a secure context/HTTPS)!!)", false, false,false, SMPPropertyTypeEnum.STRING), UI_COOKIE_SESSION_PATH("smp.ui.session.path","","A path that must exist in the requested URL, or the browser won't send the Cookie header. Null/Empty value sets the authentication requests context by default. The forward slash (/) character is interpreted as a directory separator, and subdirectories will be matched as well: for Path=/docs, /docs, /docs/Web/, and /docs/Web/HTTP will all match", false, false,false, SMPPropertyTypeEnum.STRING), - UI_COOKIE_SESSION_IDLE_TIMEOUT_ADMIN("smp.ui.session.idle_timeout.admin","300","Specifies the time, in seconds, between client requests before the SMP will invalidate session for ADMIN users (System)!", false, false,false, SMPPropertyTypeEnum.INTEGER), - UI_COOKIE_SESSION_IDLE_TIMEOUT_USER("smp.ui.session.idle_timeout.user","1800","Specifies the time, in seconds, between client requests before the SMP will invalidate session for users (Service group, SMP Admin)", false, false,false, SMPPropertyTypeEnum.INTEGER), + UI_COOKIE_SESSION_IDLE_TIMEOUT_ADMIN("smp.ui.session.idle_timeout.admin","300","Specifies the time, in seconds, between client requests before the SMP will invalidate session for ADMIN users (System and SMP Admin)!", false, false,false, SMPPropertyTypeEnum.INTEGER), + UI_COOKIE_SESSION_IDLE_TIMEOUT_USER("smp.ui.session.idle_timeout.user","1800","Specifies the time, in seconds, between client requests before the SMP will invalidate session for users (Service group)", false, false,false, SMPPropertyTypeEnum.INTEGER), // SSO configuration SSO_CAS_ENABLED("smp.sso.cas.enabled","false","Enable/disable CAS authentication.", false, false,true, SMPPropertyTypeEnum.BOOLEAN), SSO_CAS_UI_LABEL("smp.sso.cas.ui.label","EU Login","The SSO service provider label.", false, false,true, SMPPropertyTypeEnum.STRING), diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java index c41c02ed9..512470783 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java @@ -39,20 +39,29 @@ public class SMPAuthenticationEventListener implements ApplicationListener<Authe /** * On successful authentication method validates the roles and set max session idle time before it invalidates the session. + * * @param event */ @Override - public void onApplicationEvent (AuthenticationSuccessEvent event) { - Collection<? extends GrantedAuthority> authorities = event.getAuthentication().getAuthorities(); - boolean hasAdminRole = authorities.stream().anyMatch(grantedAuthority -> StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority())); + public void onApplicationEvent(AuthenticationSuccessEvent event) { + ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (attr!= null) { + if (attr != null) { + Collection<? extends GrantedAuthority> authorities = event.getAuthentication().getAuthorities(); HttpSession session = attr.getRequest().getSession(); - int idleTimeout = (hasAdminRole ? configurationService.getSessionIdleTimeoutForAdmin() : configurationService.getSessionIdleTimeoutForUser()); - LOG.debug("Set session idle timeout [{}] for user [{}]", idleTimeout, event.getAuthentication().getName()); + int idleTimeout = getSessionTimeoutForRoles(authorities); + LOG.debug("Set session idle timeout [{}] for user [{}] with roles [{}]", idleTimeout, event.getAuthentication().getName(), authorities); session.setMaxInactiveInterval(idleTimeout); } else { - LOG.warn("Could not get ServletRequestAttributes attributes for authentication [{}]", event.getAuthentication() ); + LOG.warn("Could not get ServletRequestAttributes attributes for authentication [{}]", event.getAuthentication()); } } + + public int getSessionTimeoutForRoles(Collection<? extends GrantedAuthority> authorities) { + boolean hasAdminRole = authorities.stream().anyMatch(grantedAuthority -> + StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()) + || StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority())); + LOG.debug("has admin role [{}]", hasAdminRole); + return hasAdminRole ? configurationService.getSessionIdleTimeoutForAdmin() : configurationService.getSessionIdleTimeoutForUser(); + } } \ No newline at end of file diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java new file mode 100644 index 000000000..aff3bd013 --- /dev/null +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java @@ -0,0 +1,79 @@ +package eu.europa.ec.edelivery.smp.auth; + +import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; +import eu.europa.ec.edelivery.smp.services.ConfigurationService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.core.convert.ConversionService; +import org.springframework.security.core.GrantedAuthority; + +import javax.persistence.EntityManager; +import java.util.Arrays; +import java.util.Collection; + +import static org.junit.Assert.*; + +public class SMPAuthenticationEventListenerTest { + + ConfigurationService configurationService = Mockito.mock(ConfigurationService .class);; + // test instance + SMPAuthenticationEventListener testInstance = new SMPAuthenticationEventListener(configurationService); + + + @Test + public void getSessionTimeoutForRolesSMPAdmin() { + // Given + Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SMP_ADMIN); + // when then + assertTimeoutForAuthorities(authorities, true); + } + + @Test + public void getSessionTimeoutForRolesSystemAdmin() { + // Given + Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN); + // when then + assertTimeoutForAuthorities(authorities, true); + } + + @Test + public void getSessionTimeoutForRolesUser() { + // Given + Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP); + // when then + assertTimeoutForAuthorities(authorities, false); + } + + @Test + public void getSessionTimeoutForRolesUserAndSystem() { + // Given + Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP,SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN); + // when then + assertTimeoutForAuthorities(authorities, true); + } + + @Test + public void getSessionTimeoutForRolesUserAndSMP() { + // Given + Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP,SMPAuthority.S_AUTHORITY_SMP_ADMIN); + // when then + assertTimeoutForAuthorities(authorities, true); + } + + public void assertTimeoutForAuthorities(Collection<? extends GrantedAuthority> authorities, boolean isAdmin){ + // Given + int secondsToTimeoutAdmin = 111; + int secondsToTimeoutUser = 555; + int expected = isAdmin ? secondsToTimeoutAdmin : secondsToTimeoutUser; + // idle for admin + Mockito.doReturn(secondsToTimeoutAdmin).when(configurationService).getSessionIdleTimeoutForAdmin(); + Mockito.doReturn(secondsToTimeoutUser).when(configurationService).getSessionIdleTimeoutForUser(); + // when + int result = testInstance.getSessionTimeoutForRoles(authorities); + //then + assertEquals(expected, result); + } +} \ No newline at end of file -- GitLab