You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2019/11/20 12:45:31 UTC

[syncope] branch 2_1_X updated: [SYNCOPE-1513] Adding options to console.properties

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


View the commit online:
https://github.com/apache/syncope/commit/bd37f3d2e64b3e1d609580aebe00b0bfb84f5dae

The following commit(s) were added to refs/heads/2_1_X by this push:
     new bd37f3d  [SYNCOPE-1513] Adding options to console.properties
bd37f3d is described below

commit bd37f3d2e64b3e1d609580aebe00b0bfb84f5dae
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Wed Nov 20 13:45:02 2019 +0100

    [SYNCOPE-1513] Adding options to console.properties
---
 .../resources/archetype-resources/console/pom.xml  |  16 ---
 .../resources/archetype-resources/core/pom.xml     |   8 +-
 .../resources/archetype-resources/enduser/pom.xml  |   8 +-
 client/console/pom.xml                             |  27 ++++
 .../client/console/SyncopeConsoleApplication.java  |  20 ++-
 .../console/src/main/resources/console.properties  |  10 +-
 .../syncope/client/console/AbstractTest.java       | 141 +++++++++++++++++++++
 .../console/SyncopeConsoleApplicationTest.java     |  69 ++++++++++
 client/console/src/test/resources/log4j2.xml       |  54 ++++++++
 deb/console/pom.xml                                |  16 ---
 deb/core/pom.xml                                   |   8 +-
 deb/enduser/pom.xml                                |   8 +-
 .../src/main/resources/console.properties.template |  15 ++-
 fit/build-tools/pom.xml                            |   8 +-
 fit/console-reference/pom.xml                      |  12 --
 .../src/main/resources/console.properties          |  10 +-
 fit/core-reference/pom.xml                         |   8 +-
 .../src/test/resources/console.properties          |   9 +-
 pom.xml                                            |  16 ++-
 19 files changed, 362 insertions(+), 101 deletions(-)

diff --git a/archetype/src/main/resources/archetype-resources/console/pom.xml b/archetype/src/main/resources/archetype-resources/console/pom.xml
index fb5724c..0534f18 100644
--- a/archetype/src/main/resources/archetype-resources/console/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/console/pom.xml
@@ -63,22 +63,6 @@ under the License.
       <artifactId>slf4j-api</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.lmax</groupId>
-      <artifactId>disruptor</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/archetype/src/main/resources/archetype-resources/core/pom.xml b/archetype/src/main/resources/archetype-resources/core/pom.xml
index f951894..f2f9753 100644
--- a/archetype/src/main/resources/archetype-resources/core/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/core/pom.xml
@@ -71,21 +71,17 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
+      <artifactId>log4j-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>com.lmax</groupId>
       <artifactId>disruptor</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/archetype/src/main/resources/archetype-resources/enduser/pom.xml b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
index 1e3bb28..e7df3ce 100644
--- a/archetype/src/main/resources/archetype-resources/enduser/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
@@ -64,21 +64,17 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
+      <artifactId>log4j-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>com.lmax</groupId>
       <artifactId>disruptor</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/client/console/pom.xml b/client/console/pom.xml
index 422abbc..e6b6b70 100644
--- a/client/console/pom.xml
+++ b/client/console/pom.xml
@@ -156,6 +156,33 @@ under the License.
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.lmax</groupId>
+      <artifactId>disruptor</artifactId>
+    </dependency>
+
+    <!-- required by wicket tester -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   
   <build>
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
index 7417758..0fd291f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
@@ -136,6 +136,17 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
         }
     }
 
+    protected void setSecurityHeaders(final Properties props, final WebResponse response) {
+        @SuppressWarnings("unchecked")
+        Enumeration<String> propNames = (Enumeration<String>) props.propertyNames();
+        while (propNames.hasMoreElements()) {
+            String name = propNames.nextElement();
+            if (name.startsWith("security.headers.")) {
+                response.setHeader(StringUtils.substringAfter(name, "security.headers."), props.getProperty(name));
+            }
+        }
+    }
+
     @Override
     protected void init() {
         super.init();
@@ -169,8 +180,6 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
         maxPoolSize = Integer.valueOf(props.getProperty("topology.maxPoolSize", "10"));
         queueCapacity = Integer.valueOf(props.getProperty("topology.queueCapacity", "50"));
 
-        String csrf = props.getProperty("csrf");
-
         // process page properties
         pageClasses = new HashMap<>();
         populatePageClasses(props);
@@ -201,7 +210,7 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
         getMarkupSettings().setStripWicketTags(true);
         getMarkupSettings().setCompressWhitespace(true);
 
-        if (BooleanUtils.toBoolean(csrf)) {
+        if (BooleanUtils.toBoolean(props.getProperty("csrf"))) {
             getRequestCycleListeners().add(new WebSocketAwareCsrfPreventionRequestCycleListener());
         }
         getRequestCycleListeners().add(new SyncopeConsoleRequestCycleListener());
@@ -210,10 +219,7 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
             @Override
             public void onEndRequest(final RequestCycle cycle) {
                 if (cycle.getResponse() instanceof WebResponse && !(cycle.getResponse() instanceof WebSocketResponse)) {
-                    WebResponse response = (WebResponse) cycle.getResponse();
-                    response.setHeader("X-XSS-Protection", "1; mode=block");
-                    response.setHeader("X-Content-Type-Options", "nosniff");
-                    response.setHeader("X-Frame-Options", "sameorigin");
+                    setSecurityHeaders(props, (WebResponse) cycle.getResponse());
                 }
             }
         });
diff --git a/client/console/src/main/resources/console.properties b/client/console/src/main/resources/console.properties
index 0e262cb..e8ac65e 100644
--- a/client/console/src/main/resources/console.properties
+++ b/client/console/src/main/resources/console.properties
@@ -29,8 +29,6 @@ maxUploadFileSizeMB=5
 # Max wait time on apply changes from modals/wizards (given in seconds)
 maxWaitTimeOnApplyChanges=30
 
-csrf=true
-
 reconciliationReportKey=c3520ad9-179f-49e7-b315-d684d216dd97
 
 page.dashboard=org.apache.syncope.client.console.pages.Dashboard
@@ -49,3 +47,11 @@ page.parameters=org.apache.syncope.client.console.pages.Parameters
 topology.corePoolSize=10
 topology.maxPoolSize=20
 topology.queueCapacity=50
+
+csrf=true
+
+security.headers.X-XSS-Protection=1; mode=block
+security.headers.Strict-Transport-Security=max-age=31536000; includeSubDomains; preload
+security.headers.X-Content-Type-Options=nosniff
+security.headers.X-Frame-Options=sameorigin
+#security.headers.Content-Security-Policy=default-src https:
diff --git a/client/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java b/client/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
new file mode 100644
index 0000000..6e4372b
--- /dev/null
+++ b/client/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.stream.Stream;
+import javax.servlet.ServletContext;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.jaxrs.client.Client;
+import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
+import org.apache.syncope.client.console.init.ConsoleInitializer;
+import org.apache.syncope.client.console.init.MIMETypesLoader;
+import org.apache.syncope.client.lib.AuthenticationHandler;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.info.NumbersInfo;
+import org.apache.syncope.common.lib.info.PlatformInfo;
+import org.apache.syncope.common.lib.info.SystemInfo;
+import org.apache.syncope.common.lib.to.DomainTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.rest.api.service.DomainService;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.wicket.util.tester.WicketTester;
+import org.junit.jupiter.api.BeforeAll;
+
+public abstract class AbstractTest {
+
+    protected static Properties PROPS;
+
+    public interface SyncopeServiceClient extends SyncopeService, Client {
+    }
+
+    @BeforeAll
+    public static void loadProps() throws IOException {
+        PROPS = new Properties();
+        try (InputStream is = AbstractTest.class.getResourceAsStream("/console.properties")) {
+            PROPS.load(is);
+        }
+    }
+
+    protected static final WicketTester TESTER = new WicketTester(new SyncopeConsoleApplication() {
+
+        @Override
+        protected void init() {
+            ServletContext ctx = getServletContext();
+            ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
+            lookup.load();
+            ctx.setAttribute(ConsoleInitializer.CLASSPATH_LOOKUP, lookup);
+
+            MIMETypesLoader mimeTypes = new MIMETypesLoader();
+            mimeTypes.load();
+            ctx.setAttribute(ConsoleInitializer.MIMETYPES_LOADER, mimeTypes);
+
+            super.init();
+        }
+
+        @Override
+        public List<String> getDomains() {
+            return super.getDomains();
+        }
+
+        private SyncopeService getSyncopeService() {
+            SyncopeServiceClient service = mock(SyncopeServiceClient.class);
+            when(service.type(anyString())).thenReturn(service);
+            when(service.accept(anyString())).thenReturn(service);
+
+            when(service.platform()).thenReturn(new PlatformInfo());
+            when(service.system()).thenReturn(new SystemInfo());
+
+            NumbersInfo numbersInfo = new NumbersInfo();
+            Stream.of(NumbersInfo.ConfItem.values()).
+                    forEach(item -> numbersInfo.getConfCompleteness().put(item.name(), true));
+            when(service.numbers()).thenReturn(numbersInfo);
+
+            return service;
+        }
+
+        private UserTO getUserTO() {
+            UserTO userTO = new UserTO();
+            userTO.setUsername("username");
+            return userTO;
+        }
+
+        private DomainService getDomainService() {
+            DomainService domainService = mock(DomainService.class);
+            DomainTO domainTO = new DomainTO();
+            domainTO.setKey(SyncopeConstants.MASTER_DOMAIN);
+            when(domainService.list()).thenReturn(Collections.singletonList(domainTO));
+            return domainService;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public SyncopeClientFactoryBean newClientFactory() {
+            SyncopeClient client = mock(SyncopeClient.class);
+
+            when(client.self()).thenReturn(Pair.of(new HashMap<>(), getUserTO()));
+
+            SyncopeService syncopeService = getSyncopeService();
+            when(client.getService(SyncopeService.class)).thenReturn(syncopeService);
+
+            DomainService domainService = getDomainService();
+            when(client.getService(DomainService.class)).thenReturn(domainService);
+
+            SyncopeClientFactoryBean clientFactory = mock(SyncopeClientFactoryBean.class);
+            when(clientFactory.setDomain(any())).thenReturn(clientFactory);
+            when(clientFactory.create(any(AuthenticationHandler.class))).thenReturn(client);
+            when(clientFactory.create(anyString(), anyString())).thenReturn(client);
+
+            return clientFactory;
+        }
+    });
+
+}
diff --git a/client/console/src/test/java/org/apache/syncope/client/console/SyncopeConsoleApplicationTest.java b/client/console/src/test/java/org/apache/syncope/client/console/SyncopeConsoleApplicationTest.java
new file mode 100644
index 0000000..a1f0bd1
--- /dev/null
+++ b/client/console/src/test/java/org/apache/syncope/client/console/SyncopeConsoleApplicationTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.pages.Dashboard;
+import org.apache.syncope.client.console.pages.Login;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.jupiter.api.Test;
+
+public class SyncopeConsoleApplicationTest extends AbstractTest {
+
+    private Map<String, String> getConfiguredSecurityHeaders() throws IOException {
+        Map<String, String> securityHeaders = new HashMap<>();
+
+        @SuppressWarnings("unchecked")
+        Enumeration<String> propNames = (Enumeration<String>) PROPS.propertyNames();
+        while (propNames.hasMoreElements()) {
+            String name = propNames.nextElement();
+            if (name.startsWith("security.headers.")) {
+                securityHeaders.put(StringUtils.substringAfter(name, "security.headers."), PROPS.getProperty(name));
+            }
+        }
+
+        return securityHeaders;
+    }
+
+    @Test
+    public void securityHeaders() throws IOException {
+        Map<String, String> securityHeaders = getConfiguredSecurityHeaders();
+        assertEquals(4, securityHeaders.size());
+
+        // 1. anonymous
+        TESTER.startPage(Login.class);
+        TESTER.assertRenderedPage(Login.class);
+        securityHeaders.forEach((key, value) -> assertEquals(value, TESTER.getLastResponse().getHeader(key)));
+
+        // 2. authenticated
+        FormTester formTester = TESTER.newFormTester("login");
+        formTester.setValue("username", "username");
+        formTester.setValue("password", "password");
+        formTester.submit("submit");
+
+        TESTER.assertRenderedPage(Dashboard.class);
+        securityHeaders.forEach((key, value) -> assertEquals(value, TESTER.getLastResponse().getHeader(key)));
+    }
+}
diff --git a/client/console/src/test/resources/log4j2.xml b/client/console/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..28257a5
--- /dev/null
+++ b/client/console/src/test/resources/log4j2.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<configuration status="WARN">
+
+  <appenders>
+
+    <Console name="main" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
+    </Console>
+    
+  </appenders>
+
+  <loggers>
+
+    <asyncLogger name="org.apache.syncope.client.lib" additivity="false" level="OFF">
+      <appender-ref ref="main"/>
+    </asyncLogger>
+
+    <asyncLogger name="org.apache.syncope.client.console" additivity="false" level="ERROR">
+      <appender-ref ref="main"/>
+    </asyncLogger>
+
+    <asyncLogger name="org.apache.wicket" additivity="false" level="ERROR">
+      <appender-ref ref="main"/>
+    </asyncLogger>
+    
+    <asyncLogger name="org.apache.cxf" additivity="false" level="ERROR">
+      <appender-ref ref="main"/>
+    </asyncLogger>
+    
+    <root level="ERROR">
+      <appender-ref ref="main"/>
+    </root>
+  
+  </loggers>
+  
+</configuration>
diff --git a/deb/console/pom.xml b/deb/console/pom.xml
index e71a7d1..60c0f1a 100644
--- a/deb/console/pom.xml
+++ b/deb/console/pom.xml
@@ -75,22 +75,6 @@ under the License.
       <artifactId>slf4j-api</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.lmax</groupId>
-      <artifactId>disruptor</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/deb/core/pom.xml b/deb/core/pom.xml
index a126c4d..743edc9 100644
--- a/deb/core/pom.xml
+++ b/deb/core/pom.xml
@@ -121,21 +121,17 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
+      <artifactId>log4j-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>com.lmax</groupId>
       <artifactId>disruptor</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/deb/enduser/pom.xml b/deb/enduser/pom.xml
index 3fd6f0a..0aa559a 100644
--- a/deb/enduser/pom.xml
+++ b/deb/enduser/pom.xml
@@ -68,21 +68,17 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
+      <artifactId>log4j-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>com.lmax</groupId>
       <artifactId>disruptor</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/docker/console/src/main/resources/console.properties.template b/docker/console/src/main/resources/console.properties.template
index 8789cb5..29490cc 100644
--- a/docker/console/src/main/resources/console.properties.template
+++ b/docker/console/src/main/resources/console.properties.template
@@ -31,15 +31,12 @@ maxUploadFileSizeMB=5
 # Max wait time on apply changes from modals/wizards (given in seconds)
 maxWaitTimeOnApplyChanges=30
 
-csrf=true
-
 reconciliationReportKey=c3520ad9-179f-49e7-b315-d684d216dd97
 
 page.dashboard=org.apache.syncope.client.console.pages.Dashboard
 page.realms=org.apache.syncope.client.console.pages.Realms
 page.topology=org.apache.syncope.client.console.topology.Topology
 page.reports=org.apache.syncope.client.console.pages.Reports
-page.workflow=org.apache.syncope.client.console.pages.Workflow
 page.audit=org.apache.syncope.client.console.pages.Audit
 page.implementations=org.apache.syncope.client.console.pages.Implementations
 page.logs=org.apache.syncope.client.console.pages.Logs
@@ -48,3 +45,15 @@ page.types=org.apache.syncope.client.console.pages.Types
 page.policies=org.apache.syncope.client.console.pages.Policies
 page.notifications=org.apache.syncope.client.console.pages.Notifications
 page.parameters=org.apache.syncope.client.console.pages.Parameters
+
+topology.corePoolSize=10
+topology.maxPoolSize=20
+topology.queueCapacity=50
+
+csrf=true
+
+security.headers.X-XSS-Protection=1; mode=block
+security.headers.Strict-Transport-Security=max-age=31536000; includeSubDomains; preload
+security.headers.X-Content-Type-Options=nosniff
+security.headers.X-Frame-Options=sameorigin
+#security.headers.Content-Security-Policy=default-src https:
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index 46b02d3..2a5c9d5 100644
--- a/fit/build-tools/pom.xml
+++ b/fit/build-tools/pom.xml
@@ -216,21 +216,17 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
+      <artifactId>log4j-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>com.lmax</groupId>
       <artifactId>disruptor</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml
index 6b12521..220ef5b 100644
--- a/fit/console-reference/pom.xml
+++ b/fit/console-reference/pom.xml
@@ -93,18 +93,6 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.lmax</groupId>
-      <artifactId>disruptor</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
diff --git a/fit/console-reference/src/main/resources/console.properties b/fit/console-reference/src/main/resources/console.properties
index fbba1d6..28e1822 100644
--- a/fit/console-reference/src/main/resources/console.properties
+++ b/fit/console-reference/src/main/resources/console.properties
@@ -29,8 +29,6 @@ maxUploadFileSizeMB=5
 # Max wait time on apply changes from modals/wizards (given in seconds)
 maxWaitTimeOnApplyChanges=30
 
-csrf=true
-
 reconciliationReportKey=c3520ad9-179f-49e7-b315-d684d216dd97
 
 page.dashboard=org.apache.syncope.client.console.pages.Dashboard
@@ -49,3 +47,11 @@ page.parameters=org.apache.syncope.client.console.pages.Parameters
 topology.corePoolSize=50
 topology.maxPoolSize=100
 topology.queueCapacity=10
+
+csrf=true
+
+security.headers.X-XSS-Protection=1; mode=block
+security.headers.Strict-Transport-Security=max-age=31536000; includeSubDomains; preload
+security.headers.X-Content-Type-Options=nosniff
+security.headers.X-Frame-Options=sameorigin
+#security.headers.Content-Security-Policy=default-src https:
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 517a63d..d980a12 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -79,21 +79,17 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
+      <artifactId>log4j-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>com.lmax</groupId>
       <artifactId>disruptor</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <scope>provided</scope>
diff --git a/fit/core-reference/src/test/resources/console.properties b/fit/core-reference/src/test/resources/console.properties
index 648782b..28e1822 100644
--- a/fit/core-reference/src/test/resources/console.properties
+++ b/fit/core-reference/src/test/resources/console.properties
@@ -29,8 +29,6 @@ maxUploadFileSizeMB=5
 # Max wait time on apply changes from modals/wizards (given in seconds)
 maxWaitTimeOnApplyChanges=30
 
-csrf=false
-
 reconciliationReportKey=c3520ad9-179f-49e7-b315-d684d216dd97
 
 page.dashboard=org.apache.syncope.client.console.pages.Dashboard
@@ -50,3 +48,10 @@ topology.corePoolSize=50
 topology.maxPoolSize=100
 topology.queueCapacity=10
 
+csrf=true
+
+security.headers.X-XSS-Protection=1; mode=block
+security.headers.Strict-Transport-Security=max-age=31536000; includeSubDomains; preload
+security.headers.X-Content-Type-Options=nosniff
+security.headers.X-Frame-Options=sameorigin
+#security.headers.Content-Security-Policy=default-src https:
diff --git a/pom.xml b/pom.xml
index 61e5a51..9f53446 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1399,16 +1399,16 @@ under the License.
         <version>${log4j.version}</version>
       </dependency>
       <dependency>
-        <groupId>com.lmax</groupId>
-        <artifactId>disruptor</artifactId>
-        <version>${disruptor.version}</version>
-      </dependency>
-      <dependency>
         <groupId>org.apache.logging.log4j</groupId>
         <artifactId>log4j-slf4j-impl</artifactId>
         <version>${log4j.version}</version>
       </dependency>
       <dependency>
+        <groupId>com.lmax</groupId>
+        <artifactId>disruptor</artifactId>
+        <version>${disruptor.version}</version>
+      </dependency>
+      <dependency>
         <groupId>commons-logging</groupId>
         <artifactId>commons-logging</artifactId>
         <version>${commons-logging.version}</version>
@@ -1790,6 +1790,12 @@ under the License.
         <scope>test</scope>
       </dependency>
       <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-core</artifactId>
+        <version>3.1.0</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
         <groupId>org.junit.jupiter</groupId>
         <artifactId>junit-jupiter</artifactId>
         <version>${junit.version}</version>