diff --git a/config/application.tmpl b/config/application.tmpl
index 053f28947172e5f4404fbbcada65f157f5f6bf01..cb8167e694800fb6cfc1f384d420a0c7c065e9b7 100644
--- a/config/application.tmpl
+++ b/config/application.tmpl
@@ -1,26 +1,28 @@
 # Configuration template for the portal running inside a Docker container
 
+
+### EMBEDDED SERVER CONFIGURATION ###
+server:
+  servlet:
+    contextPath: "/services"
+  port: 8080
+  forward-headers-strategy: native
+
+
 ### LOG LEVELS ###
 logging:
   level:
     root: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
-    org: {{ default .Env.LOG_LEVEL_FRAMEWORK "ERROR" }}
     eu:
       hbp: {{ default .Env.LOG_LEVEL "INFO" }}
 
 
-### AUTHENTICATION ###
-authentication:
-  enabled: {{ default .Env.AUTHENTICATION "true" }}
-
-
 ### DATABASE CONFIGURATION ###
 spring:
-  portal-datasource:
-    url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://88.197.53.106:5432/portal" }}
-    schema: {{ default .Env.PORTAL_DB_SCHEMA "public" }}
-    username: {{ default .Env.PORTAL_DB_USER "postgres" }}
-    password: {{ .Env.PORTAL_DB_PASSWORD }}
+  datasource:
+    url: {{ default .Env.PORTAL_DB_URL "jdbc:postgresql://172.17.0.1:5433/portal" }}
+    username: {{ default .Env.PORTAL_DB_USER "portal" }}
+    password: {{ default .Env.PORTAL_DB_PASSWORD "portalpwd" }}
     driver-class-name: org.postgresql.Driver
   data:
     jpa:
@@ -28,12 +30,33 @@ spring:
         bootstrap-mode: default
   jpa:
     hibernate:
-      dialect: org.hibernate.dialect.PostgreSQL9Dialect
       ddl-auto: validate
-
   mvc:
     pathmatch:
       matching-strategy: ant_path_matcher
+  security:
+    oauth2:
+      client:
+        registration:
+          keycloak:
+            authorization-grant-type: authorization_code
+            client-id: {{ .Env.KEYCLOAK_REALM }}
+            client-secret: {{ .Env.KEYCLOAK_CLIENT_SECRET }}
+            provider: keycloak
+            scope: openid
+            redirect-uri: http://172.17.0.1/${server.servlet.contextPath}/login/oauth2/code/{{ .Env.KEYCLOAK_REALM }}
+        provider:
+          keycloak:
+            issuer-uri: http://172.17.0.1/auth/realms/{{ .Env.KEYCLOAK_REALM }}
+            user-name-attribute: preferred_username
+
+
+### AUTHENTICATION ###
+authentication:
+  enabled: {{ default .Env.AUTHENTICATION "1" }}
+  all_datasets_allowed_claim: research_dataset_all
+  all_experiments_allowed_claim: research_experiment_all
+  dataset_claim_prefix: research_dataset_
 
 
 ### EXTERNAL SERVICES ###
@@ -43,44 +66,13 @@ services:
     algorithmsUrl: {{ .Env.EXAREME2_URL}}/algorithms
     attributesUrl: {{ .Env.EXAREME2_URL}}/data_models_attributes
     cdesMetadataUrl: {{ .Env.EXAREME2_URL}}/cdes_metadata
-
   exareme:
     queryExaremeUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/query
     algorithmsUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/algorithms.json
 
 
-### KEYCLOAK ###
-keycloak:
-  enabled: true
-  auth-server-url: {{ .Env.KEYCLOAK_AUTH_URL }}
-  realm: {{ .Env.KEYCLOAK_REALM }}
-  resource: {{ .Env.KEYCLOAK_CLIENT_ID }}
-  use-resource-role-mappings: true
-  enable-basic-auth: true
-  credentials:
-    secret: {{ .Env.KEYCLOAK_CLIENT_SECRET }}
-  principal-attribute: "preferred_username"
-  ssl-required: {{ .Env.KEYCLOAK_SSL_REQUIRED }}
-
 ### EXTERNAL FILES ###
 # Files are imported when building the docker image
 files:
   pathologies_json: "file:/opt/portal/api/pathologies.json"
   disabledAlgorithms_json: "file:{{ .Env.DISABLED_ALGORITHMS_CONFIG_PATH}}"
-
-
-### EMBEDDED SERVER CONFIGURATION ###
-server:
-  servlet:
-    contextPath: "/services"
-  port: 8080
-  forward-headers-strategy: native
-
-
-### ENDPOINTS ###
-endpoints:
-  enabled: true
-  health:
-    enabled: true
-    endpoint: /health
-    sensitive: false
diff --git a/pom.xml b/pom.xml
index 54473e10ad46575f5f03bb9029a3991d4e339332..d5a08e25c3b4037cad62906e587b3d50ec173864 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,17 +13,17 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>2.7.13</version>
+        <version>3.1.2</version>
     </parent>
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <java.version>17</java.version>
-        <spring-context.version>5.3.29</spring-context.version>
+        <spring-context.version>6.0.11</spring-context.version>
         <postgresql.version>42.6.0</postgresql.version>
-        <hibernate.version>5.6.15.Final</hibernate.version>
+        <jakarta.version>3.1.0</jakarta.version>
+        <hibernate.version>6.2.7.Final</hibernate.version>
         <flyway-core.version>4.2.0</flyway-core.version>
-        <keycloak-spring.version>13.0.1</keycloak-spring.version>
         <gson.version>2.10.1</gson.version>
         <commons-dbcp.version>2.9.0</commons-dbcp.version>
         <lombok.version>1.18.28</lombok.version>
@@ -48,13 +48,17 @@
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-rest</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-actuator</artifactId>
+            <artifactId>spring-boot-starter-oauth2-client</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.data</groupId>
@@ -65,17 +69,12 @@
             <artifactId>spring-data-jpa</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-spring-boot-starter</artifactId>
-            <version>${keycloak-spring.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-spring-security-adapter</artifactId>
-            <version>${keycloak-spring.version}</version>
+            <groupId>jakarta.persistence</groupId>
+            <artifactId>jakarta.persistence-api</artifactId>
+            <version>${jakarta.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.hibernate</groupId>
+            <groupId>org.hibernate.orm</groupId>
             <artifactId>hibernate-core</artifactId>
             <version>${hibernate.version}</version>
         </dependency>
diff --git a/src/main/java/eu/hbp/mip/configurations/PersistenceConfiguration.java b/src/main/java/eu/hbp/mip/configurations/PersistenceConfiguration.java
index b87771dbd484ba692e9e82135bc4e1661dffe2ce..23df36815b2305ed368cd9fa3e1aa0339528af9f 100644
--- a/src/main/java/eu/hbp/mip/configurations/PersistenceConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/PersistenceConfiguration.java
@@ -20,8 +20,8 @@ import javax.sql.DataSource;
 public class PersistenceConfiguration {
 
     @Primary
-    @Bean(name = "portal-datasource")
-    @ConfigurationProperties(prefix = "spring.portal-datasource")
+    @Bean(name = "datasource")
+    @ConfigurationProperties(prefix = "spring.datasource")
     public DataSource portalDataSource() {
         return DataSourceBuilder.create().build();
     }
diff --git a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
index bb27681312d0f145c0d04b6c46ca66f7b788a1c6..e57bc1432126556c0c931b56ce94c9947052f631 100644
--- a/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configurations/SecurityConfiguration.java
@@ -1,2 +1,129 @@
-package eu.hbp.mip.configurations;public class SecurityConfiguration {
+package eu.hbp.mip.configurations;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
+import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler;
+import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
+import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
+import org.springframework.security.oauth2.core.AuthorizationGrantType;
+import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
+import org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Configuration
+@EnableWebSecurity
+@EnableMethodSecurity
+public class SecurityConfiguration {
+
+    @Value("${authentication.enabled}")
+    private boolean authenticationEnabled;
+
+    // This Bean is used when there is no authentication and there is no keycloak server running due to this bug:
+    // https://github.com/spring-projects/spring-security/issues/11397#issuecomment-1655906163
+    // So we overwrite the ClientRegistrationRepository Bean to avoid the IP server lookup.
+    @Bean
+    @ConditionalOnProperty(prefix = "authentication", name = "enabled", havingValue = "0")
+    public ClientRegistrationRepository clientRegistrationRepository() {
+        ClientRegistration dummyRegistration = ClientRegistration.withRegistrationId("dummy")
+                .clientId("google-client-id")
+                .clientSecret("google-client-secret")
+                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+                .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
+                .scope("openid")
+                .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
+                .tokenUri("https://www.googleapis.com/oauth2/v4/token")
+                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
+                .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
+                .build();
+        return new InMemoryClientRegistrationRepository(dummyRegistration);
+    }
+
+    @Bean
+    SecurityFilterChain clientSecurityFilterChain(HttpSecurity http, ClientRegistrationRepository clientRegistrationRepo) throws Exception {
+        if (authenticationEnabled) {
+            http.authorizeHttpRequests(auth -> auth
+                    .requestMatchers("/login/**", "/oauth2/**", "/actuator/**").permitAll()
+                    .requestMatchers("/**").authenticated()
+            );
+
+            http.oauth2Login(login -> login.defaultSuccessUrl("/", true));
+
+            // Open ID Logout
+            // https://docs.spring.io/spring-security/reference/servlet/oauth2/login/advanced.html#oauth2login-advanced-oidc-logout
+            OidcClientInitiatedLogoutSuccessHandler successHandler = new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepo);
+            successHandler.setPostLogoutRedirectUri("{baseUrl}");
+            http.logout(logout -> logout.logoutSuccessHandler(successHandler));
+
+            // ---> XSRF Token handling
+            // https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#deferred-csrf-token
+            // https://stackoverflow.com/questions/74447118/csrf-protection-not-working-with-spring-security-6
+            XorCsrfTokenRequestAttributeHandler requestHandler = new XorCsrfTokenRequestAttributeHandler();
+            // set the name of the attribute the CsrfToken will be populated on
+            requestHandler.setCsrfRequestAttributeName(null);
+
+            // Change cookie path
+            CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
+            tokenRepository.setCookiePath("/");
+
+            http.csrf((csrf) -> csrf
+                    .csrfTokenRepository(tokenRepository)
+                    .csrfTokenRequestHandler(requestHandler::handle)
+                    .ignoringRequestMatchers("/logout")
+            );
+            // <--- XSRF Token handling
+
+
+        } else {
+            http.authorizeHttpRequests(auth -> auth
+                    .requestMatchers("/**").permitAll()
+            );
+            http.csrf((csrf) -> csrf
+                    .ignoringRequestMatchers("/**")
+            );
+
+        }
+        return http.build();
+    }
+
+    @Component
+    @RequiredArgsConstructor
+    static class GrantedAuthoritiesMapperImpl implements GrantedAuthoritiesMapper {
+        private static Collection<GrantedAuthority> extractAuthorities(Map<String, Object> claims) {
+            return ((Collection<String>) claims.get("authorities")).stream()
+                    .map(SimpleGrantedAuthority::new)
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        public Collection<? extends GrantedAuthority> mapAuthorities(Collection<? extends GrantedAuthority> authorities) {
+            Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
+
+            authorities.forEach(authority -> {
+                if (authority instanceof OidcUserAuthority oidcUserAuthority) {
+                    mappedAuthorities.addAll(extractAuthorities(oidcUserAuthority.getIdToken().getClaims()));
+                }
+            });
+
+            return mappedAuthorities;
+        }
+    }
 }
+
diff --git a/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java b/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
index 9b8a42cbee92f2d962b8beb45545042989fefdd5..5aaeaa77ea48fd959bbee2205f246abb4ae6bbff 100644
--- a/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/ActiveUserAPI.java
@@ -4,9 +4,8 @@ import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.utils.Logger;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.*;
 
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
@@ -20,18 +19,19 @@ public class ActiveUserAPI {
         this.activeUserService = activeUserService;
     }
 
-    @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<UserDAO> getTheActiveUser() {
-        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser");
+    @GetMapping
+    public ResponseEntity<UserDAO> getTheActiveUser(Authentication authentication) {
+        UserDAO activeUser = activeUserService.getActiveUser(authentication);
+        Logger logger = new Logger(activeUser.getUsername(), "(GET) /activeUser");
         logger.LogUserAction("Loading the details of the activeUser");
 
-        return ResponseEntity.ok(activeUserService.getActiveUser());
+        return ResponseEntity.ok(activeUser);
     }
 
-    @RequestMapping(value = "/agreeNDA", method = RequestMethod.POST)
-    public ResponseEntity<UserDAO> activeUserServiceAgreesToNDA() {
-        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /activeUser/agreeNDA");
+    @PostMapping(value = "/agreeNDA")
+    public ResponseEntity<UserDAO> activeUserServiceAgreesToNDA(Authentication authentication) {
+        Logger logger = new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(GET) /activeUser/agreeNDA");
         logger.LogUserAction("The user agreed to the NDA");
-        return ResponseEntity.ok(activeUserService.agreeToNDA());
+        return ResponseEntity.ok(activeUserService.agreeToNDA(authentication));
     }
 }
diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
index 771c61fb84b8f1ec6148fe05b9f26b92ce4f8d6f..181c5eb22bda24b15971bbd9a47b565e4766ad24 100644
--- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsAPI.java
@@ -5,6 +5,8 @@ import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.services.AlgorithmService;
 import eu.hbp.mip.utils.Logger;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
@@ -24,9 +26,9 @@ public class AlgorithmsAPI {
         this.algorithmService = algorithmService;
     }
 
-    @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<List<ExaremeAlgorithmDTO>> getAlgorithms() {
-        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /algorithms");
+    @GetMapping
+    public ResponseEntity<List<ExaremeAlgorithmDTO>> getAlgorithms(Authentication authentication) {
+        Logger logger = new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(GET) /algorithms");
         logger.LogUserAction("Executing...");
         List<ExaremeAlgorithmDTO> algorithms = algorithmService.getAlgorithms();
 
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
index c722918d92e9af9a6318902a87b0aa371f5eecd2..bdb82d8a20f528b23a71d6d19106a14d58e89981 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
@@ -4,7 +4,6 @@ package eu.hbp.mip.controllers;
 import eu.hbp.mip.models.DTOs.ExperimentDTO;
 import eu.hbp.mip.services.ActiveUserService;
 import eu.hbp.mip.services.ExperimentService;
-import eu.hbp.mip.utils.JsonConverters;
 import eu.hbp.mip.utils.Logger;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -22,6 +21,7 @@ public class ExperimentAPI {
 
     private final ExperimentService experimentService;
     private final ActiveUserService activeUserService;
+
     public ExperimentAPI(
             ExperimentService experimentService,
             ActiveUserService activeUserService
@@ -30,19 +30,19 @@ public class ExperimentAPI {
         this.activeUserService = activeUserService;
     }
 
-    @RequestMapping(method = RequestMethod.GET)
-    public ResponseEntity<String> getExperiments(Authentication authentication,
-            @RequestParam(name = "name", required = false) String name,
-            @RequestParam(name = "algorithm", required = false) String algorithm,
-            @RequestParam(name = "shared", required = false) Boolean shared,
-            @RequestParam(name = "viewed", required = false) Boolean viewed,
-            @RequestParam(name = "includeShared", required = false, defaultValue = "true") boolean includeShared,
-            @RequestParam(name = "orderBy", required = false, defaultValue = "created") String orderBy,
-            @RequestParam(name = "descending", required = false, defaultValue = "true") Boolean descending,
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "10") int size
+    @GetMapping
+    public ResponseEntity<Object> getExperiments(Authentication authentication,
+                                                 @RequestParam(name = "name", required = false) String name,
+                                                 @RequestParam(name = "algorithm", required = false) String algorithm,
+                                                 @RequestParam(name = "shared", required = false) Boolean shared,
+                                                 @RequestParam(name = "viewed", required = false) Boolean viewed,
+                                                 @RequestParam(name = "includeShared", required = false, defaultValue = "true") boolean includeShared,
+                                                 @RequestParam(name = "orderBy", required = false, defaultValue = "created") String orderBy,
+                                                 @RequestParam(name = "descending", required = false, defaultValue = "true") Boolean descending,
+                                                 @RequestParam(defaultValue = "0") int page,
+                                                 @RequestParam(defaultValue = "10") int size
     ) {
-        Map experiments = experimentService.getExperiments(authentication,
+        Map<String, Object> experiments = experimentService.getExperiments(authentication,
                 name,
                 algorithm,
                 shared,
@@ -52,43 +52,61 @@ public class ExperimentAPI {
                 size,
                 orderBy,
                 descending,
-                new Logger(activeUserService.getActiveUser().getUsername(),"(GET) /experiments"));
-        return new ResponseEntity(experiments, HttpStatus.OK);
+                new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(GET) /experiments"));
+        return new ResponseEntity<>(experiments, HttpStatus.OK);
     }
 
 
-    @RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
-    public ResponseEntity<String> getExperiment(Authentication authentication, @PathVariable("uuid") String uuid) {
-        ExperimentDTO experimentDTO = experimentService.getExperiment(authentication, uuid, new Logger(activeUserService.getActiveUser().getUsername(),"(GET) /experiments/{uuid}"));
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    @GetMapping(value = "/{uuid}")
+    public ResponseEntity<ExperimentDTO> getExperiment(Authentication authentication, @PathVariable("uuid") String uuid) {
+        ExperimentDTO experimentDTO = experimentService.getExperiment(
+                authentication, uuid,
+                new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(GET) /experiments/{uuid}")
+        );
+        return new ResponseEntity<>(experimentDTO, HttpStatus.OK);
     }
 
 
-    @RequestMapping(method = RequestMethod.POST)
-    public ResponseEntity<String> createExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        experimentDTO = experimentService.createExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(),"(POST) /experiments"));
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.CREATED);
+    @PostMapping
+    public ResponseEntity<ExperimentDTO> createExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
+        experimentDTO = experimentService.createExperiment(
+                authentication, experimentDTO,
+                new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(POST) /experiments")
+        );
+        return new ResponseEntity<>(experimentDTO, HttpStatus.CREATED);
     }
 
 
-    @RequestMapping(value = "/{uuid}", method = RequestMethod.PATCH)
-    public ResponseEntity<String> updateExperiment(@RequestBody ExperimentDTO experimentDTO, @PathVariable("uuid") String uuid) {
-        experimentDTO = experimentService.updateExperiment(uuid, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(),"(PATCH) /experiments/{uuid}"));
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    @PatchMapping(value = "/{uuid}")
+    public ResponseEntity<ExperimentDTO> updateExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO, @PathVariable("uuid") String uuid) {
+        experimentDTO = experimentService.updateExperiment(
+                authentication,
+                uuid,
+                experimentDTO,
+                new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(PATCH) /experiments/{uuid}")
+        );
+        return new ResponseEntity<>(experimentDTO, HttpStatus.OK);
     }
 
 
     @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE)
-    public ResponseEntity<String> deleteExperiment(@PathVariable("uuid") String uuid) {
-        experimentService.deleteExperiment(uuid, new Logger(activeUserService.getActiveUser().getUsername(), "(DELETE) /experiments/{uuid}"));
+    public ResponseEntity<String> deleteExperiment(Authentication authentication, @PathVariable("uuid") String uuid) {
+        experimentService.deleteExperiment(
+                authentication,
+                uuid,
+                new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(DELETE) /experiments/{uuid}")
+        );
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
 
-    @RequestMapping(value = "/transient", method = RequestMethod.POST)
-    public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        experimentDTO = experimentService.
-                runTransientExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(), "(POST) /experiments/transient"));
-        return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
+    @PostMapping (value = "/transient")
+    public ResponseEntity<ExperimentDTO> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
+        experimentDTO = experimentService.runTransientExperiment(
+                authentication,
+                experimentDTO,
+                new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(POST) /experiments/transient")
+        );
+        return new ResponseEntity<>(experimentDTO, HttpStatus.OK);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
index 6e1b643c28818b77aec635f7566855816d92778a..73c12fbea00972faac57caca22024a846362b718 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesAPI.java
@@ -11,6 +11,7 @@ import eu.hbp.mip.utils.Exceptions.InternalServerError;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
@@ -34,15 +35,19 @@ public class PathologiesAPI {
 
     @Value("#{'${services.exareme2.cdesMetadataUrl}'}")
     private String exareme2CDEsMetadataUrl;
+
     private final ActiveUserService activeUserService;
 
-    public PathologiesAPI(ActiveUserService activeUserService) {
+    private final ClaimUtils claimUtils;
+
+    public PathologiesAPI(ActiveUserService activeUserService, ClaimUtils claimUtils) {
         this.activeUserService = activeUserService;
+        this.claimUtils = claimUtils;
     }
 
-    @RequestMapping(name = "/pathologies", method = RequestMethod.GET)
+    @GetMapping
     public ResponseEntity<String> getPathologies(Authentication authentication) {
-        Logger logger = new Logger(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies");
+        Logger logger = new Logger(activeUserService.getActiveUser(authentication).getUsername(), "(GET) /pathologies");
         logger.LogUserAction("Loading pathologies ...");
 
         Map<String, List<PathologyDTO.EnumerationDTO>> datasetsPerPathology = getExareme2DatasetsPerPathology(logger);
@@ -70,7 +75,7 @@ public class PathologiesAPI {
         }
 
         logger.LogUserAction("Successfully loaded all authorized pathologies");
-        return ResponseEntity.ok().body(gson.toJson(ClaimUtils.getAuthorizedPathologies(logger, authentication, pathologyDTOS)));
+        return ResponseEntity.ok().body(gson.toJson(claimUtils.getAuthorizedPathologies(logger, authentication, pathologyDTOS)));
     }
 
     public Map<String, List<PathologyDTO.EnumerationDTO>> getExareme2DatasetsPerPathology(Logger logger) {
@@ -93,13 +98,11 @@ public class PathologiesAPI {
 
         exareme2CDEsMetadata.forEach( (pathology, cdePerDataset) ->  {
             List<PathologyDTO.EnumerationDTO> pathologyDatasetDTOS = new ArrayList<>();
-            Map datasetEnumerations = (Map) cdePerDataset.get("dataset").getEnumerations();
-            datasetEnumerations.forEach((code, label) ->  pathologyDatasetDTOS.add(new PathologyDTO.EnumerationDTO((String) code, (String) label)));
+            Map<String, String> datasetEnumerations = (Map<String, String>) cdePerDataset.get("dataset").getEnumerations();
+            datasetEnumerations.forEach((code, label) ->  pathologyDatasetDTOS.add(new PathologyDTO.EnumerationDTO(code, label)));
             datasetsPerPathology.put(pathology, pathologyDatasetDTOS);
         });
 
-
-
         return datasetsPerPathology;
     }
 
diff --git a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
index 49b4f6670b0274dd0a506f3e2a35b41b9117d0aa..244b55d6f1f3d64514952335cead321525b2001b 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/ExperimentDAO.java
@@ -3,16 +3,15 @@ package eu.hbp.mip.models.DAOs;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.google.gson.Gson;
 import com.google.gson.annotations.Expose;
+import jakarta.persistence.*;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 
-import javax.persistence.*;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Date;
+import java.util.UUID;
+
 
-/**
- * Created by habfast on 21/04/16.
- */
 @Entity
 @Data
 @AllArgsConstructor
@@ -25,7 +24,6 @@ public class ExperimentDAO {
     @Expose
     @Id
     @Column(columnDefinition = "uuid", updatable = false)
-    @org.hibernate.annotations.Type(type = "pg-uuid")
     private UUID uuid;
 
     @Expose
diff --git a/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java b/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
index acbab0e320a294d5e17aefe74b612b5b8d6794bc..d1ab17988297d2d938d1c5818e7313a78a442bed 100644
--- a/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
+++ b/src/main/java/eu/hbp/mip/models/DAOs/UserDAO.java
@@ -9,9 +9,9 @@ import com.google.gson.annotations.Expose;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
 
 @Entity
 @Data
diff --git a/src/main/java/eu/hbp/mip/models/DTOs/UserDTO.java b/src/main/java/eu/hbp/mip/models/DTOs/UserDTO.java
index 7550807246c05be32e70f67c544124aa96f5d292..448b50f1a506adce7bb7fae1bd68d1b7b0fed3b9 100644
--- a/src/main/java/eu/hbp/mip/models/DTOs/UserDTO.java
+++ b/src/main/java/eu/hbp/mip/models/DTOs/UserDTO.java
@@ -20,7 +20,6 @@ public class UserDTO {
     private String fullname;
 
     public UserDTO(){
-
     }
 
     public UserDTO(UserDAO userdao) {
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
index fb119582801741bbaee66cea3e189bd8704d27a0..733737cee94ec5aaa56fe92af5405abe8c41b37c 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
@@ -12,12 +12,8 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.repository.CrudRepository;
 
 import java.util.Date;
-import java.util.Optional;
 import java.util.UUID;
 
-/**
- * Created by mirco on 11.07.16.
- */
 
 public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID>, JpaSpecificationExecutor<ExperimentDAO>
 {
@@ -69,30 +65,12 @@ public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID
         try {
             save(experimentDAO);
         } catch (Exception e) {
-            logger.LogUserAction("Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            logger.LogUserAction("Attempted to save changes to database but an error occurred  : " + e.getMessage() + ".");
             throw new InternalServerError(e.getMessage());
         }
         return experimentDAO;
     }
 
-    default void saveExperiment(ExperimentDAO experimentDAO, Logger logger) {
-
-        logger.LogUserAction(" id : " + experimentDAO.getUuid());
-        logger.LogUserAction(" algorithm : " + experimentDAO.getAlgorithm());
-        logger.LogUserAction(" name : " + experimentDAO.getName());
-        logger.LogUserAction(" historyId : " + experimentDAO.getWorkflowHistoryId());
-        logger.LogUserAction(" status : " + experimentDAO.getStatus());
-
-        try {
-            save(experimentDAO);
-        } catch (Exception e) {
-            logger.LogUserAction("Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
-            throw new InternalServerError(e.getMessage());
-        }
-
-        logger.LogUserAction("Saved experiment");
-    }
-
     default void finishExperiment(ExperimentDAO experimentDAO, Logger logger) {
         experimentDAO.setFinished(new Date());
 
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentSpecifications.java b/src/main/java/eu/hbp/mip/repositories/ExperimentSpecifications.java
index 08423757f2c937a2c0f823063e675726dc2335d0..ba1f7babccedb3a49906fff66fd1cd5fe732a77c 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentSpecifications.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentSpecifications.java
@@ -1,13 +1,14 @@
 package eu.hbp.mip.repositories;
 
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
-import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.utils.Exceptions.BadRequestException;
+import jakarta.persistence.criteria.*;
+import lombok.NonNull;
 import org.springframework.data.jpa.domain.Specification;
 
-import javax.persistence.criteria.*;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 public class ExperimentSpecifications {
     public static class ExperimentWithName implements Specification<ExperimentDAO> {
@@ -20,7 +21,7 @@ public class ExperimentSpecifications {
             this.regExp = name;
         }
 
-        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+        public Predicate toPredicate(@NonNull Root<ExperimentDAO> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder cb) {
             if (name == null) {
                 return cb.isTrue(cb.literal(true));
             } else {
@@ -29,6 +30,16 @@ public class ExperimentSpecifications {
 
             return cb.like(cb.lower(root.get("name")), this.regExp.toLowerCase());
         }
+
+        @Override
+        public @NonNull Specification<ExperimentDAO> and(Specification<ExperimentDAO> other) {
+            return Specification.super.and(other);
+        }
+
+        @Override
+        public @NonNull Specification<ExperimentDAO> or(Specification<ExperimentDAO> other) {
+            return Specification.super.or(other);
+        }
     }
 
     public static class ExperimentWithAlgorithm implements Specification<ExperimentDAO> {
@@ -39,7 +50,7 @@ public class ExperimentSpecifications {
             this.algorithm = algorithm;
         }
 
-        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+        public Predicate toPredicate(@NonNull Root<ExperimentDAO> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder cb) {
             if (algorithm == null) {
                 return cb.isTrue(cb.literal(true));
             }
@@ -56,7 +67,7 @@ public class ExperimentSpecifications {
             this.viewed = viewed;
         }
 
-        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+        public Predicate toPredicate(@NonNull Root<ExperimentDAO> root, @NonNull CriteriaQuery<?> query, @NonNull CriteriaBuilder cb) {
             if (viewed == null) {
                 return cb.isTrue(cb.literal(true)); // always true = no filtering
             }
@@ -72,7 +83,7 @@ public class ExperimentSpecifications {
             this.shared = shared;
         }
 
-        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+        public Predicate toPredicate(@NonNull Root<ExperimentDAO> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder cb) {
             if (shared == null) {
                 return cb.isTrue(cb.literal(true));
             }
@@ -88,11 +99,11 @@ public class ExperimentSpecifications {
             this.username = username;
         }
 
-        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+        public Predicate toPredicate(@NonNull Root<ExperimentDAO> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder cb) {
             if (username == null) {
                 return cb.isTrue(cb.literal(true));
             }
-            Join<ExperimentDAO, UserDAO> experimentDAOUserDAOJoin = root.join("createdBy");
+            Join<Object, Object> experimentDAOUserDAOJoin = root.join("createdBy");
             return cb.equal(experimentDAOUserDAOJoin.get("username"), username);
         }
     }
@@ -105,11 +116,11 @@ public class ExperimentSpecifications {
             this.shared = shared;
         }
 
-        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+        public Predicate toPredicate(@NonNull Root<ExperimentDAO> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder cb) {
             if (!shared) {
                 return cb.isTrue(cb.literal(false));
             }
-            return cb.equal(root.get("shared"), shared);
+            return cb.equal(root.get("shared"), true);
         }
     }
 
@@ -123,13 +134,10 @@ public class ExperimentSpecifications {
                 this.orderBy = orderBy;
             else
                 throw new BadRequestException("Please provide proper column to order by.");
-            if (descending == null)
-                this.descending = true;
-            else
-                this.descending = descending;
+            this.descending = Objects.requireNonNullElse(descending, true);
         }
 
-        public Predicate toPredicate(Root<ExperimentDAO> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
+        public Predicate toPredicate(@NonNull Root<ExperimentDAO> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder cb) {
             if (descending) {
                 criteriaQuery.orderBy(cb.desc(root.get(orderBy)));
             } else {
diff --git a/src/main/java/eu/hbp/mip/repositories/UserRepository.java b/src/main/java/eu/hbp/mip/repositories/UserRepository.java
index 99ae0b1dcfc237e875e7ba458175ae8441ec8c8e..cbfdc5b5bfd5bc392775470a961c2b1eabf5fd9d 100644
--- a/src/main/java/eu/hbp/mip/repositories/UserRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/UserRepository.java
@@ -3,11 +3,6 @@ package eu.hbp.mip.repositories;
 import eu.hbp.mip.models.DAOs.UserDAO;
 import org.springframework.data.repository.CrudRepository;
 
-/**
- * Created by mirco on 11.07.16.
- */
-
 public interface UserRepository extends CrudRepository<UserDAO, String> {
-
     UserDAO findByUsername(String username);
 }
diff --git a/src/main/java/eu/hbp/mip/services/ActiveUserService.java b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
index 48252160ebd694b7eba73e66117b6370d5b8edb1..816a9a15b7d2585098b2074eb60b1098a507b60d 100644
--- a/src/main/java/eu/hbp/mip/services/ActiveUserService.java
+++ b/src/main/java/eu/hbp/mip/services/ActiveUserService.java
@@ -2,24 +2,25 @@ package eu.hbp.mip.services;
 
 import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.repositories.UserRepository;
-import org.keycloak.KeycloakPrincipal;
-import org.keycloak.representations.IDToken;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.ScopedProxyMode;
-import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
+import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
 import org.springframework.stereotype.Component;
 
 import java.util.Objects;
 
+
 @Component
 @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
 public class ActiveUserService {
 
-    @Value("#{'${authentication.enabled}'}")
+    @Value("${authentication.enabled}")
     private boolean authenticationIsEnabled;
 
-    private UserDAO user;
+    private UserDAO activeUserDetails;
 
     private final UserRepository userRepository;
 
@@ -33,50 +34,48 @@ public class ActiveUserService {
      *
      * @return the userDAO
      */
-    public UserDAO getActiveUser() {
+    public UserDAO getActiveUser(Authentication authentication) {
+        // TODO getActiveUser should not be called in so many places.
+        // It should be called in the controller and then passed internally in the other methods as UserDTO.
+        // TODO getActiveUser should return a UserDTO instead of a DAO
 
-        // User already loaded
-        if (user != null)
-            return user;
+        if (activeUserDetails != null)
+            return activeUserDetails;
 
         // If Authentication is OFF, create anonymous user with accepted NDA
         if (!authenticationIsEnabled) {
-            user = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com", "anonymousId");
-            user.setAgreeNDA(true);
-            userRepository.save(user);
-            return user;
+            activeUserDetails = new UserDAO("anonymous", "anonymous", "anonymous@anonymous.com", "anonymousId");
+            activeUserDetails.setAgreeNDA(true);
+            userRepository.save(activeUserDetails);
+            return activeUserDetails;
         }
 
-        // If authentication is ON get user info from Token
-        KeycloakPrincipal keycloakPrincipal =
-                (KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        IDToken idToken = keycloakPrincipal.getKeycloakSecurityContext().getIdToken();
-        user = new UserDAO(idToken.getPreferredUsername(), idToken.getName(), idToken.getEmail(), idToken.getId());
-
-        UserDAO userInDatabase = userRepository.findByUsername(user.getUsername());
-        if (userInDatabase == null) {
-            userRepository.save(user);
-            return user;
-        }
 
-        if (!Objects.equals(user.getEmail(),userInDatabase.getEmail())
-            || !Objects.equals(user.getFullname(),userInDatabase.getFullname())
-        ) {
-            userInDatabase.setFullname(user.getFullname());
-            userInDatabase.setEmail(user.getEmail());
+        OidcUserInfo userinfo = ((DefaultOidcUser) authentication.getPrincipal()).getUserInfo();
+        activeUserDetails = new UserDAO(userinfo.getPreferredUsername(), userinfo.getFullName(), userinfo.getEmail(), userinfo.getSubject());
+
+        UserDAO activeUserDatabaseDetails = userRepository.findByUsername(activeUserDetails.getUsername());
+        if (activeUserDatabaseDetails != null) {
+            if ((!Objects.equals(activeUserDetails.getEmail(), activeUserDatabaseDetails.getEmail()))
+                    || !Objects.equals(activeUserDetails.getFullname(), activeUserDatabaseDetails.getFullname())
+            ) {
+                // Fullname and email are the only values allowed to change.
+                // username is the PK in our database and subjectid is the PK in keycloak
+                activeUserDatabaseDetails.setFullname(activeUserDetails.getFullname());
+                activeUserDatabaseDetails.setEmail(activeUserDetails.getEmail());
+            }
+            activeUserDetails = activeUserDatabaseDetails;
         }
-
-        user = userInDatabase;
-        userRepository.save(user);
-        return user;
+        userRepository.save(activeUserDetails);
+        return activeUserDetails;
     }
 
-    public UserDAO agreeToNDA() {
-        getActiveUser();
+    public UserDAO agreeToNDA(Authentication authentication) {
+        getActiveUser(authentication);
 
-        user.setAgreeNDA(true);
-        userRepository.save(user);
+        activeUserDetails.setAgreeNDA(true);
+        userRepository.save(activeUserDetails);
 
-        return user;
+        return activeUserDetails;
     }
 }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 081f44ea979571add6e1fdbf99f70067f1b83ead..7715def2481483126980c3069ab828ebc75f1c6b 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -31,21 +31,27 @@ import java.util.*;
 @Service
 public class ExperimentService {
 
-
     private static final Gson gson = new Gson();
     private final ActiveUserService activeUserService;
     private final AlgorithmService algorithmService;
+    private final ClaimUtils claimUtils;
     private final ExperimentRepository experimentRepository;
-    @Value("#{'${services.exareme.queryExaremeUrl}'}")
+    @Value("${services.exareme.queryExaremeUrl}")
     private String queryExaremeUrl;
-    @Value("#{'${services.exareme2.algorithmsUrl}'}")
+    @Value("${services.exareme2.algorithmsUrl}")
     private String exareme2AlgorithmsUrl;
-    @Value("#{'${authentication.enabled}'}")
+    @Value("${authentication.enabled}")
     private boolean authenticationIsEnabled;
 
-    public ExperimentService(ActiveUserService activeUserService, AlgorithmService algorithmService, ExperimentRepository experimentRepository) {
+    public ExperimentService(
+            ActiveUserService activeUserService,
+            AlgorithmService algorithmService,
+            ClaimUtils claimUtils,
+            ExperimentRepository experimentRepository
+    ) {
         this.algorithmService = algorithmService;
         this.activeUserService = activeUserService;
+        this.claimUtils = claimUtils;
         this.experimentRepository = experimentRepository;
     }
 
@@ -60,19 +66,19 @@ public class ExperimentService {
      * @param page          is the page that is required to be retrieved
      * @param size          is the size of each page
      * @param orderBy       is the column that is required to ordered by
-     * @param descending    is a boolean to determine if the experiments will be order by descending or ascending
+     * @param descending    is a boolean to determine if the experiments will be ordered by descending or ascending order
      * @param logger        contains username and the endpoint.
      * @return a map experiments
      */
 
-    public Map getExperiments(Authentication authentication, String name, String algorithm, Boolean shared, Boolean viewed, boolean includeShared, int page, int size, String orderBy, Boolean descending, Logger logger) {
+    public Map<String, Object> getExperiments(Authentication authentication, String name, String algorithm, Boolean shared, Boolean viewed, boolean includeShared, int page, int size, String orderBy, Boolean descending, Logger logger) {
 
-        UserDAO user = activeUserService.getActiveUser();
+        UserDAO user = activeUserService.getActiveUser(authentication);
         logger.LogUserAction("Listing my experiments.");
         if (size > 50)
             throw new BadRequestException("Invalid size input, max size is 50.");
         Specification<ExperimentDAO> spec;
-        if (!authenticationIsEnabled || ClaimUtils.validateAccessRightsOnExperiments(authentication, logger)) {
+        if (!authenticationIsEnabled || claimUtils.validateAccessRightsOnALLExperiments(authentication, logger)) {
             spec = Specification
                     .where(new ExperimentSpecifications.ExperimentWithName(name))
                     .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
@@ -118,7 +124,7 @@ public class ExperimentService {
     public ExperimentDTO getExperiment(Authentication authentication, String uuid, Logger logger) {
 
         ExperimentDAO experimentDAO;
-        UserDAO user = activeUserService.getActiveUser();
+        UserDAO user = activeUserService.getActiveUser(authentication);
 
         logger.LogUserAction("Loading Experiment with uuid : " + uuid);
 
@@ -127,7 +133,7 @@ public class ExperimentService {
                 authenticationIsEnabled
                         && !experimentDAO.isShared()
                         && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())
-                        && !ClaimUtils.validateAccessRightsOnExperiments(authentication, logger)
+                        && !claimUtils.validateAccessRightsOnALLExperiments(authentication, logger)
         ) {
             logger.LogUserAction("Accessing Experiment is unauthorized.");
             throw new UnauthorizedException("You don't have access to the experiment.");
@@ -159,10 +165,10 @@ public class ExperimentService {
 
         if (authenticationIsEnabled) {
             String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, logger);
-            ClaimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger);
+            claimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger);
         }
 
-        return createSynchronousExperiment(experimentDTO, algorithmEngineName, logger);
+        return createSynchronousExperiment(authentication, experimentDTO, algorithmEngineName, logger);
 
     }
 
@@ -189,7 +195,7 @@ public class ExperimentService {
 
         if (authenticationIsEnabled) {
             String experimentDatasets = getDatasetFromExperimentParameters(experimentDTO, logger);
-            ClaimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger);
+            claimUtils.validateAccessRightsOnDatasets(authentication, experimentDatasets, logger);
         }
 
         logger.LogUserAction("Completed, returning: " + experimentDTO);
@@ -216,9 +222,9 @@ public class ExperimentService {
      * @param experimentDTO is the experiment information to be updated
      * @param logger        contains username and the endpoint.
      */
-    public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, Logger logger) {
+    public ExperimentDTO updateExperiment(Authentication authentication, String uuid, ExperimentDTO experimentDTO, Logger logger) {
         ExperimentDAO experimentDAO;
-        UserDAO user = activeUserService.getActiveUser();
+        UserDAO user = activeUserService.getActiveUser(authentication);
         logger.LogUserAction("Updating experiment with uuid : " + uuid + ".");
 
         experimentDAO = experimentRepository.loadExperiment(uuid, logger);
@@ -259,9 +265,9 @@ public class ExperimentService {
      * @param uuid   is the id of the experiment to be deleted
      * @param logger contains username and the endpoint.
      */
-    public void deleteExperiment(String uuid, Logger logger) {
+    public void deleteExperiment(Authentication authentication, String uuid, Logger logger) {
         ExperimentDAO experimentDAO;
-        UserDAO user = activeUserService.getActiveUser();
+        UserDAO user = activeUserService.getActiveUser(authentication);
         logger.LogUserAction("Deleting experiment with uuid : " + uuid + ".");
 
         experimentDAO = experimentRepository.loadExperiment(uuid, logger);
@@ -408,11 +414,11 @@ public class ExperimentService {
      * @param logger        contains username and the endpoint.
      * @return the experiment information that was retrieved from exareme
      */
-    private ExperimentDTO createSynchronousExperiment(ExperimentDTO experimentDTO, String algorithmEngineName, Logger logger) {
+    private ExperimentDTO createSynchronousExperiment(Authentication authentication, ExperimentDTO experimentDTO, String algorithmEngineName, Logger logger) {
 
         logger.LogUserAction("Running the algorithm...");
 
-        ExperimentDAO experimentDAO = experimentRepository.createExperimentInTheDatabase(experimentDTO, activeUserService.getActiveUser(), logger);
+        ExperimentDAO experimentDAO = experimentRepository.createExperimentInTheDatabase(experimentDTO, activeUserService.getActiveUser(authentication), logger);
         experimentDTO.setUuid(experimentDAO.getUuid());
         logger.LogUserAction("Created experiment with uuid :" + experimentDAO.getUuid());
 
diff --git a/src/main/java/eu/hbp/mip/utils/CORSFilter.java b/src/main/java/eu/hbp/mip/utils/CORSFilter.java
deleted file mode 100644
index 7d77b9022ef0855f0f5d6decf84601d0a00f75b0..0000000000000000000000000000000000000000
--- a/src/main/java/eu/hbp/mip/utils/CORSFilter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package eu.hbp.mip.utils;
-
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-
-/**
- * CORS Filter used only for development.
- *
- * Allows requests from all possible origins.
- */
-public class CORSFilter implements Filter {
-    @Override
-    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
-        HttpServletResponse response = (HttpServletResponse) res;
-        response.setHeader("Access-Control-Allow-Origin", "*");
-        response.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE");
-        response.setHeader("Access-Control-Max-Age", "3600");
-        response.setHeader("Access-Control-Allow-Headers", "*");
-        response.setHeader("Access-Control-Request-Headers", "*");
-        chain.doFilter(req, res);
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
index 650ac9c65fc4cf461159a3d94673d406cfe19dce..27b79af9fc5f291d5112b7fc1c22dcb0ced8893e 100644
--- a/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
+++ b/src/main/java/eu/hbp/mip/utils/ClaimUtils.java
@@ -1,42 +1,56 @@
 package eu.hbp.mip.utils;
 
-import com.google.gson.Gson;
 import eu.hbp.mip.models.DTOs.PathologyDTO;
-import eu.hbp.mip.utils.Exceptions.InternalServerError;
 import eu.hbp.mip.utils.Exceptions.UnauthorizedException;
-import org.keycloak.KeycloakPrincipal;
-import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
 
-import java.util.*;
-
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
+@Component
 public class ClaimUtils {
 
-    private static final Gson gson = new Gson();
+    @Value("${authentication.all_datasets_allowed_claim}")
+    private String allDatasetsAllowedClaim;
+
+    @Value("${authentication.all_experiments_allowed_claim}")
+    private String allExperimentsAllowedClaim;
 
-    public static String allDatasetsAllowedClaim() {
-        return "research_dataset_all";
+    @Value("${authentication.dataset_claim_prefix}")
+    private String datasetClaimPrefix;
+
+    private String getDatasetClaim(String datasetCode) {
+        return datasetClaimPrefix + datasetCode.toLowerCase();
     }
 
-    public static String allExperimentsAllowedClaim() {
-        return "research_experiment_all";
+    private static boolean hasRoleAccess(ArrayList<String> authorities, String role, Logger logger) {
+        List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
+                .replaceAll("[\\s+\\]\\[]", "").split(","));
+
+        logger.LogUserAction("User Claims: " + userClaims);
+        return userClaims.contains(role.toLowerCase());
     }
 
-    public static String getDatasetClaim(String datasetCode) {
-        return "research_dataset_" + datasetCode.toLowerCase();
+    private static ArrayList<String> getAuthorityRoles(Authentication authentication) {
+        return (ArrayList<String>) authentication.getAuthorities().stream()
+                .map(Object::toString)
+                .collect(Collectors.toList());
     }
 
-    public static void validateAccessRightsOnDatasets(Authentication authentication,
+    public void validateAccessRightsOnDatasets(Authentication authentication,
                                                       String experimentDatasets, Logger logger) {
 
-        ArrayList<String> authorities = getKeycloakAuthorities(authentication, logger);
+        ArrayList<String> authorities = getAuthorityRoles(authentication);
 
         // Don't check for dataset claims if "super" claim exists allowing everything
-        if (!hasRoleAccess(authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
+        if (!hasRoleAccess(authorities, allDatasetsAllowedClaim, logger)) {
 
             for (String dataset : experimentDatasets.split(",")) {
-                String datasetRole = ClaimUtils.getDatasetClaim(dataset);
+                String datasetRole = getDatasetClaim(dataset);
                 if (!hasRoleAccess(authorities, datasetRole, logger)) {
                     logger.LogUserAction("You are not allowed to use dataset: " + dataset);
                     throw new UnauthorizedException("You are not authorized to use these datasets.");
@@ -46,70 +60,43 @@ public class ClaimUtils {
         }
     }
 
-    public static boolean validateAccessRightsOnExperiments(Authentication authentication, Logger logger) {
-
-        ArrayList<String> authorities = getKeycloakAuthorities(authentication, logger);
-
-        // Check for experiment_all claims
-        return  hasRoleAccess(authorities, ClaimUtils.allExperimentsAllowedClaim(), logger);
+    public boolean validateAccessRightsOnALLExperiments(Authentication authentication, Logger logger) {
+        ArrayList<String> authorities = getAuthorityRoles(authentication);
+        return hasRoleAccess(authorities, allExperimentsAllowedClaim, logger);
     }
 
-    public static List<PathologyDTO> getAuthorizedPathologies(Logger logger, Authentication authentication,
+    public List<PathologyDTO> getAuthorizedPathologies(Logger logger, Authentication authentication,
                                                               List<PathologyDTO> allPathologies) {
-        // --- Providing only the allowed pathologies/datasets to the user  ---
-        logger.LogUserAction("Filter out the unauthorised datasets.");
 
-        ArrayList<String> authorities = getKeycloakAuthorities(authentication, logger);
-
-        // If the "dataset_all" claim exists then return everything
-        if (hasRoleAccess(authorities, ClaimUtils.allDatasetsAllowedClaim(), logger)) {
-            return allPathologies;
-        }
+        ArrayList<String> authorities = getAuthorityRoles(authentication);
 
         List<PathologyDTO> userPathologies = new ArrayList<>();
-        for (PathologyDTO curPathology : allPathologies) {
-            List<PathologyDTO.EnumerationDTO> userPathologyDatasets = new ArrayList<>();
-            for (PathologyDTO.EnumerationDTO dataset : curPathology.getDatasets()) {
-                if (hasRoleAccess(authorities, ClaimUtils.getDatasetClaim(dataset.getCode()), logger)) {
-                    logger.LogUserAction("Added dataset: " + dataset.getCode());
-                    userPathologyDatasets.add(dataset);
+        if (hasRoleAccess(authorities, allDatasetsAllowedClaim, logger)) {
+            userPathologies = allPathologies;
+
+        } else {
+            for (PathologyDTO curPathology : allPathologies) {
+                List<PathologyDTO.EnumerationDTO> userPathologyDatasets = new ArrayList<>();
+                for (PathologyDTO.EnumerationDTO dataset : curPathology.getDatasets()) {
+                    if (hasRoleAccess(authorities, getDatasetClaim(dataset.getCode()), logger)) {
+                        userPathologyDatasets.add(dataset);
+                    }
                 }
-            }
 
-            if (userPathologyDatasets.size() > 0) {
-                logger.LogUserAction("Added pathology '" + curPathology.getLabel()
-                                + "' with datasets: '" + userPathologyDatasets + "'");
-
-                PathologyDTO userPathology = new PathologyDTO();
-                userPathology.setCode(curPathology.getCode());
-                userPathology.setLabel(curPathology.getLabel());
-                userPathology.setMetadataHierarchyDTO(curPathology.getMetadataHierarchyDTO());
-                userPathology.setDatasets(userPathologyDatasets);
-                userPathologies.add(userPathology);
+                if (userPathologyDatasets.size() > 0) {
+                    PathologyDTO userPathology = new PathologyDTO();
+                    userPathology.setCode(curPathology.getCode());
+                    userPathology.setLabel(curPathology.getLabel());
+                    userPathology.setMetadataHierarchyDTO(curPathology.getMetadataHierarchyDTO());
+                    userPathology.setDatasets(userPathologyDatasets);
+                    userPathologies.add(userPathology);
+                }
             }
         }
 
+        String userPathologiesSTR = userPathologies.stream().map(PathologyDTO::toString)
+                .collect(Collectors.joining(", "));
+        logger.LogUserAction("Allowed pathologies: [" + userPathologiesSTR + "]");
         return userPathologies;
     }
-
-    private static boolean  hasRoleAccess(ArrayList<String> authorities, String role, Logger logger)
-    {
-        List<String> userClaims = Arrays.asList(authorities.toString().toLowerCase()
-                .replaceAll("[\\s+\\]\\[]", "").split(","));
-
-        logger.LogUserAction("User Claims: " + userClaims);
-        return userClaims.contains(role.toLowerCase());
-    }
-
-    private static ArrayList<String> getKeycloakAuthorities(Authentication authentication, Logger logger){
-        KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
-        KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) token.getPrincipal();
-        if(keycloakPrincipal.getKeycloakSecurityContext().getIdToken().getOtherClaims().get("authorities") == null)
-        {
-            logger.LogUserAction("Your user has no roles.");
-            throw new InternalServerError("Your user has no roles.");
-        }
-
-         return (ArrayList<String>)keycloakPrincipal.getKeycloakSecurityContext().getIdToken().getOtherClaims().get("authorities");
-    }
 }
diff --git a/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
index 09d39615150bad777d94689cdd96c2f24143da84..bd4fd42aefada816b535e173f9dd3b772e1dbea2 100644
--- a/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
+++ b/src/main/java/eu/hbp/mip/utils/ControllerExceptionHandler.java
@@ -14,6 +14,8 @@ import java.util.Date;
 @ControllerAdvice
 public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
 
+    public record ErrorMessage (int statusCode, Date timestamp, String message, String description) {}
+
     @ExceptionHandler(ExperimentNotFoundException.class)
     public ResponseEntity<Object> handleExperimentNotFoundException(ExperimentNotFoundException ex, WebRequest request) {
         ErrorMessage message = new ErrorMessage(
@@ -47,21 +49,6 @@ public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
         return new ResponseEntity<>(message, HttpStatus.UNAUTHORIZED);
     }
 
-    @ExceptionHandler(InternalServerError.class)
-    public ResponseEntity<ErrorMessage> handleInternalServerError(InternalServerError er, WebRequest request) {
-        logger.error("An unexpected exception occurred: " + er.getClass() +
-                "\nMessage: " + er.getMessage() +
-                "\nStacktrace: " + Arrays.toString(er.getStackTrace()).replaceAll(", ", "\n")
-        );
-        ErrorMessage message = new ErrorMessage(
-                HttpStatus.INTERNAL_SERVER_ERROR.value(),
-                new Date(),
-                er.getMessage(),
-                request.getDescription(false));
-
-        return new ResponseEntity<>(message, HttpStatus.INTERNAL_SERVER_ERROR);
-    }
-
     @ExceptionHandler(NoContent.class)
     public ResponseEntity<ErrorMessage> handleNoContent(NoContent nc, WebRequest request) {
         ErrorMessage message = new ErrorMessage(
@@ -73,7 +60,7 @@ public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
         return new ResponseEntity<>(message, HttpStatus.NO_CONTENT);
     }
 
-    @ExceptionHandler(Exception.class)
+    @ExceptionHandler({InternalServerError.class, Exception.class})
     public ResponseEntity<ErrorMessage> globalExceptionHandler(Exception ex, WebRequest request) {
         logger.error("An unexpected exception occurred: " + ex.getClass() +
                 "\nMessage: " + ex.getMessage() +
diff --git a/src/main/java/eu/hbp/mip/utils/CustomResourceLoader.java b/src/main/java/eu/hbp/mip/utils/CustomResourceLoader.java
index b7365762468eb400aaec9172e13ae3960986a773..d4d5d407f9be349ecd2a46abdf45b1bc4ae02598 100644
--- a/src/main/java/eu/hbp/mip/utils/CustomResourceLoader.java
+++ b/src/main/java/eu/hbp/mip/utils/CustomResourceLoader.java
@@ -1,5 +1,6 @@
 package eu.hbp.mip.utils;
 
+import lombok.NonNull;
 import org.springframework.context.ResourceLoaderAware;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.ResourceLoader;
@@ -10,7 +11,7 @@ public class CustomResourceLoader implements ResourceLoaderAware {
 
     private ResourceLoader resourceLoader;
 
-    public void setResourceLoader(ResourceLoader resourceLoader) {
+    public void setResourceLoader(@NonNull ResourceLoader resourceLoader) {
         this.resourceLoader = resourceLoader;
     }
 
diff --git a/src/main/java/eu/hbp/mip/utils/ErrorMessage.java b/src/main/java/eu/hbp/mip/utils/ErrorMessage.java
deleted file mode 100644
index fdaac15921a846f710f89398a799c41e7a6befa8..0000000000000000000000000000000000000000
--- a/src/main/java/eu/hbp/mip/utils/ErrorMessage.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package eu.hbp.mip.utils;
-
-
-import java.util.Date;
-
-public class ErrorMessage {
-    private final int statusCode;
-    private final Date timestamp;
-    private final String message;
-    private final String description;
-
-    public ErrorMessage(int statusCode, Date timestamp, String message, String description) {
-        this.statusCode = statusCode;
-        this.timestamp = timestamp;
-        this.message = message;
-        this.description = description;
-    }
-
-    public int getStatusCode() {
-        return statusCode;
-    }
-
-    public Date getTimestamp() {
-        return timestamp;
-    }
-
-    public String getMessage() {
-        return message;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-}
diff --git a/src/main/java/eu/hbp/mip/utils/HTTPUtil.java b/src/main/java/eu/hbp/mip/utils/HTTPUtil.java
index fdd7a9179cbb95bccb73277212a2dd29b5b20b41..2ef8e58809e88d0c50eecb4659e0186f1bff3dbc 100644
--- a/src/main/java/eu/hbp/mip/utils/HTTPUtil.java
+++ b/src/main/java/eu/hbp/mip/utils/HTTPUtil.java
@@ -18,19 +18,14 @@ public class HTTPUtil {
         throw new IllegalAccessError("HTTPUtil class");
     }
 
-    public static int sendGet(String url, StringBuilder resp) throws IOException {
-        return sendHTTP(url, "", resp, "GET", null);
+    public static void sendGet(String url, StringBuilder resp) throws IOException {
+        sendHTTP(url, "", resp, "GET", null);
     }
 
     public static int sendPost(String url, String query, StringBuilder resp) throws IOException {
         return sendHTTP(url, query, resp, "POST", null);
     }
 
-    public static int sendAuthorizedHTTP(String url, String query, StringBuilder resp, String httpVerb,
-                                         String authorization) throws IOException {
-        return sendHTTP(url, query, resp, httpVerb, authorization);
-    }
-
     private static int sendHTTP(String url, String query, StringBuilder resp, String httpVerb, String authorization)
             throws IOException {
 
diff --git a/src/main/java/eu/hbp/mip/utils/InputStreamConverter.java b/src/main/java/eu/hbp/mip/utils/InputStreamConverter.java
index ebb8f9d999dd73381ae9f203c12361fb381cba9b..050ba74604f9dc9b658ee439e4ed8a94ac518414 100644
--- a/src/main/java/eu/hbp/mip/utils/InputStreamConverter.java
+++ b/src/main/java/eu/hbp/mip/utils/InputStreamConverter.java
@@ -8,6 +8,7 @@ import java.nio.charset.StandardCharsets;
 public class InputStreamConverter {
 
     // Pure Java
+    // https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java
     public static String convertInputStreamToString(InputStream inputStream) throws IOException {
         ByteArrayOutputStream result = new ByteArrayOutputStream();
         byte[] buffer = new byte[1024];
@@ -16,6 +17,6 @@ public class InputStreamConverter {
             result.write(buffer, 0, length);
         }
 
-        return result.toString(StandardCharsets.UTF_8.name());
+        return result.toString(StandardCharsets.UTF_8);
     }
 }
diff --git a/src/main/java/eu/hbp/mip/utils/Logger.java b/src/main/java/eu/hbp/mip/utils/Logger.java
index 7ea51d74f008f3e5eef6760fc8693dc5d69d5240..60e67c7aa8815ccb10b91909871024da4bb48a4a 100644
--- a/src/main/java/eu/hbp/mip/utils/Logger.java
+++ b/src/main/java/eu/hbp/mip/utils/Logger.java
@@ -2,8 +2,6 @@ package eu.hbp.mip.utils;
 
 import org.slf4j.LoggerFactory;
 
-import java.util.UUID;
-
 
 public class Logger {
 
@@ -11,7 +9,7 @@ public class Logger {
     private final String username;
     private final String endpoint;
 
-    public Logger(String username, String endpoint){
+    public Logger(String username, String endpoint) {
         this.username = username;
         this.endpoint = endpoint;
     }
@@ -21,11 +19,4 @@ public class Logger {
                 + "Endpoint -> " + endpoint + " ,"
                 + "Info ->  " + actionInfo);
     }
-
-    // Deprecated, should be removed
-    public static void LogBackgroundAction(String experimentName, UUID experimentId, String actionInfo) {
-        LOGGER.info(" Experiment -> " + experimentName
-                + "(" + experimentId + ") ,"
-                + "Info -> " + actionInfo);
-    }
 }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 89fb72844192a95de2b4d216623980224eb3fa97..0f6d06f61412fb761a7dd0af894b95c251187e10 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,24 +1,26 @@
 # Configuration for development purposes
 
+
+### EMBEDDED SERVER CONFIGURATION ###
+server:
+  servlet:
+    contextPath: "/services"
+  port: 8080
+  forward-headers-strategy: native
+
+
 ### LOG LEVELS ###
 logging:
   level:
-    root: "ERROR"
-    org: "ERROR"
+    root: "INFO"
     eu:
       hbp: "DEBUG"
 
 
-### AUTHENTICATION ###
-authentication:
-  enabled: false
-
-
 ### DATABASE CONFIGURATION ###
 spring:
-  portal-datasource:
+  datasource:
     url: "jdbc:postgresql://127.0.0.1:5433/portal"
-    schema: "public"
     username: "portal"
     password: "portalpwd"
     driver-class-name: org.postgresql.Driver
@@ -28,12 +30,33 @@ spring:
         bootstrap-mode: default
   jpa:
     hibernate:
-      dialect: org.hibernate.dialect.PostgreSQL9Dialect
       ddl-auto: validate
-
   mvc:
     pathmatch:
       matching-strategy: ant_path_matcher
+  security:
+    oauth2:
+      client:
+        registration:
+          keycloak:
+            authorization-grant-type: authorization_code
+            client-id: MIP
+            client-secret: dae83a6b-c769-4186-8383-f0984c6edf05
+            provider: keycloak
+            scope: openid
+            redirect-uri: http://172.17.0.1/${server.servlet.contextPath}/login/oauth2/code/MIP
+        provider:
+          keycloak:
+            user-name-attribute: preferred_username
+            issuer-uri: http://172.17.0.1/auth/realms/MIP
+
+
+### AUTHENTICATION ###
+authentication:
+  enabled: 0
+  all_datasets_allowed_claim: research_dataset_all
+  all_experiments_allowed_claim: research_experiment_all
+  dataset_claim_prefix: research_dataset_
 
 
 ### EXTERNAL SERVICES ###
@@ -48,28 +71,7 @@ services:
     algorithmsUrl: "http://127.0.0.1:9090/mining/algorithms.json"
 
 
-### KEYCLOAK ###
-keycloak:
-  enabled: true
-  auth-server-url: "https://iam.humanbrainproject.eu/auth"
-  realm: "MIP"
-  resource: "mipfedqa"
-  use-resource-role-mappings: true
-  enable-basic-auth: true
-  credentials:
-    secret: "dae83a6b-c769-4186-8383-f0984c6edf05"
-  principal-attribute: "preferred_username"
-
-
 ### EXTERNAL FILES ###
 # Files are loaded from the resources
 files:
   disabledAlgorithms_json: "classPath:/disabledAlgorithms.json"
-
-
-### EMBEDDED SERVER CONFIGURATION ###
-server:
-  servlet:
-    contextPath: "/services"
-  port: 8080
-  forward-headers-strategy: native