diff --git a/src/main/java/de/thm/arsnova/config/SecurityConfig.java b/src/main/java/de/thm/arsnova/config/SecurityConfig.java index 1e0ce9fafca24be49345b448e14cb31c0081624c..dfddcfe64451606c2cf73b93458125fc1289f4aa 100644 --- a/src/main/java/de/thm/arsnova/config/SecurityConfig.java +++ b/src/main/java/de/thm/arsnova/config/SecurityConfig.java @@ -46,6 +46,8 @@ import org.springframework.core.annotation.Order; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.ldap.core.support.LdapContextSource; +import org.springframework.security.access.intercept.RunAsManager; +import org.springframework.security.access.intercept.RunAsManagerImpl; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.cas.ServiceProperties; import org.springframework.security.cas.authentication.CasAuthenticationProvider; @@ -53,6 +55,7 @@ import org.springframework.security.cas.web.CasAuthenticationEntryPoint; import org.springframework.security.cas.web.CasAuthenticationFilter; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -60,6 +63,8 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.session.SessionRegistry; import org.springframework.security.core.session.SessionRegistryImpl; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.keygen.Base64StringKeyGenerator; +import org.springframework.security.crypto.keygen.StringKeyGenerator; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.ldap.DefaultSpringSecurityContextSource; import org.springframework.security.ldap.authentication.BindAuthenticator; @@ -87,13 +92,13 @@ import java.util.List; * Loads property file and configures components used for authentication. */ @Configuration -@EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, prePostEnabled = true) @EnableWebSecurity @Profile("!test") public class SecurityConfig extends WebSecurityConfigurerAdapter { public static final String OAUTH_CALLBACK_PATH_SUFFIX = "/auth/oauth_callback"; public static final String CAS_LOGIN_PATH_SUFFIX = "/auth/login/cas"; public static final String CAS_LOGOUT_PATH_SUFFIX = "/auth/logout/cas"; + public static final String RUN_AS_KEY_PREFIX = "RUN_AS_KEY"; private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class); @Autowired @@ -171,6 +176,20 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { } } + @Configuration + @EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, prePostEnabled = true, securedEnabled = true) + public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { + @Override + protected RunAsManager runAsManager() { + StringKeyGenerator keyGenerator = new Base64StringKeyGenerator(); + RunAsManagerImpl runAsManager = new RunAsManagerImpl(); + /* Since RunAsTokens should currently only be used internally, we generate a random key. */ + runAsManager.setKey(RUN_AS_KEY_PREFIX + keyGenerator.generateKey()); + + return runAsManager; + } + } + @PostConstruct private void init() { if ("".equals(apiPath)) { diff --git a/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java b/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java index 2e8fdd8adbb4f003907d509c3ef2c40d66627f4d..acf6a9e923d5245ba51a27a378b9d10438e58be2 100644 --- a/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java +++ b/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.PermissionEvaluator; +import org.springframework.security.access.intercept.RunAsUserToken; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; @@ -72,7 +73,7 @@ public class ApplicationPermissionEvaluator implements PermissionEvaluator { final String userId = getUserId(authentication); - return hasAdminRole(userId) + return isSystemAccess(authentication) || hasAdminRole(userId) || (targetDomainObject instanceof UserProfile && hasUserProfilePermission(userId, ((UserProfile) targetDomainObject), permission.toString())) || (targetDomainObject instanceof Room @@ -248,6 +249,11 @@ public class ApplicationPermissionEvaluator implements PermissionEvaluator { return user.getId(); } + private boolean isSystemAccess(Authentication auth) { + return auth instanceof RunAsUserToken + && auth.getAuthorities().stream().anyMatch(ga -> ga.getAuthority().equals("ROLE_RUN_AS_SYSTEM")); + } + private boolean isWebsocketAccess(Authentication auth) { return auth instanceof AnonymousAuthenticationToken && auth.getAuthorities().contains("ROLE_WEBSOCKET_ACCESS"); }