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 15:27:00 UTC
[syncope] branch master updated: [SYNCOPE-1513] Adding options to
console.properties and enduser.properties
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
View the commit online:
https://github.com/apache/syncope/commit/26e062ac6c276316f0ee1b7ec5e43440e517db9e
The following commit(s) were added to refs/heads/master by this push:
new 26e062a [SYNCOPE-1513] Adding options to console.properties and enduser.properties
26e062a is described below
commit 26e062ac6c276316f0ee1b7ec5e43440e517db9e
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Wed Nov 20 13:45:02 2019 +0100
[SYNCOPE-1513] Adding options to console.properties and
enduser.properties
---
.../syncope/client/console/AbstractTest.java | 141 +++++++++++++++++++++
.../console/SyncopeConsoleApplicationTest.java | 69 ++++++++++
client/console/src/test/resources/log4j2.xml | 54 ++++++++
.../console/panels/LinkedAccountModalPanel.java | 3 -
client/idrepo/console/pom.xml | 24 ++--
.../client/console/SyncopeWebApplication.java | 28 ++--
.../console/src/main/resources/console.properties | 16 ++-
client/idrepo/enduser/pom.xml | 8 +-
.../client/enduser/SyncopeWebApplication.java | 38 ++++--
.../enduser/src/main/resources/enduser.properties | 8 +-
.../client/enduser/pages/Login_it.properties | 2 +-
core/starter/pom.xml | 8 +-
.../enduser/src/main/resources/enduser.properties | 26 ----
fit/build-tools/pom.xml | 8 +-
.../src/main/resources/console.properties | 16 ++-
.../src/test/resources/console.properties | 9 +-
.../src/test/resources/enduser.properties | 8 +-
.../src/main/resources/enduser.properties | 8 +-
.../src/test/resources/enduser.properties | 25 ----
pom.xml | 16 ++-
sra/pom.xml | 8 +-
21 files changed, 394 insertions(+), 129 deletions(-)
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/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
index a9680e3..a5d64db 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
@@ -18,8 +18,6 @@
*/
package org.apache.syncope.client.console.panels;
-import static org.apache.syncope.client.console.panels.AbstractModalPanel.LOG;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
@@ -228,5 +226,4 @@ public class LinkedAccountModalPanel extends AbstractModalPanel<Serializable> {
private void checkAddButton() {
addAjaxLink.setVisible(SyncopeConsoleSession.get().owns(IdRepoEntitlement.USER_UPDATE));
}
-
}
diff --git a/client/idrepo/console/pom.xml b/client/idrepo/console/pom.xml
index 30523ab..86e69aa 100644
--- a/client/idrepo/console/pom.xml
+++ b/client/idrepo/console/pom.xml
@@ -117,28 +117,34 @@ 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>
+
+ <!-- required by wicket tester -->
<dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j-impl</artifactId>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
</dependency>
+
<dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <scope>provided</scope>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
</dependency>
<dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <scope>test</scope>
</dependency>
</dependencies>
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
index 0b451fa..41f69d9 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
@@ -23,7 +23,6 @@ import de.agilecoders.wicket.core.Bootstrap;
import de.agilecoders.wicket.core.settings.BootstrapSettings;
import de.agilecoders.wicket.core.settings.IBootstrapSettings;
import de.agilecoders.wicket.core.settings.SingleThemeProvider;
-
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -85,7 +84,7 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
private static final String CONSOLE_PROPERTIES = "console.properties";
public static final List<Locale> SUPPORTED_LOCALES = List.of(
- Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR"), new Locale("ru"), Locale.JAPANESE);
+ Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR"), new Locale("ru"), Locale.JAPANESE);
public static SyncopeWebApplication get() {
return (SyncopeWebApplication) WebApplication.get();
@@ -162,6 +161,17 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
}
}
+ 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));
+ }
+ }
+ }
+
private NetworkService getNetworkService() {
NetworkService ns = new NetworkService();
ns.setType(NetworkService.Type.CONSOLE);
@@ -194,8 +204,6 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
maxPoolSize = Integer.valueOf(props.getProperty("executor.maxPoolSize", "10"));
queueCapacity = Integer.valueOf(props.getProperty("executor.queueCapacity", "50"));
- boolean csrf = BooleanUtils.toBoolean(props.getProperty("csrf"));
-
// process page properties
pageClasses = new HashMap<>();
populatePageClasses(props);
@@ -222,10 +230,6 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
getMarkupSettings().setStripWicketTags(true);
getMarkupSettings().setCompressWhitespace(true);
- if (csrf) {
- getRequestCycleListeners().add(new WebSocketAwareCsrfPreventionRequestCycleListener());
- }
-
getRequestCycleListeners().add(new SyncopeUIRequestCycleListener() {
@Override
@@ -244,15 +248,15 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
}
});
+ if (BooleanUtils.toBoolean(props.getProperty("csrf"))) {
+ getRequestCycleListeners().add(new WebSocketAwareCsrfPreventionRequestCycleListener());
+ }
getRequestCycleListeners().add(new IRequestCycleListener() {
@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/idrepo/console/src/main/resources/console.properties b/client/idrepo/console/src/main/resources/console.properties
index 1929f4f..c68e3ba 100644
--- a/client/idrepo/console/src/main/resources/console.properties
+++ b/client/idrepo/console/src/main/resources/console.properties
@@ -25,8 +25,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
@@ -41,6 +39,14 @@ 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
-executor.corePoolSize=10
-executor.maxPoolSize=20
-executor.queueCapacity=50
+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/idrepo/enduser/pom.xml b/client/idrepo/enduser/pom.xml
index 2dad2c1..4291275 100644
--- a/client/idrepo/enduser/pom.xml
+++ b/client/idrepo/enduser/pom.xml
@@ -100,21 +100,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/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
index 65a8ff0..63b6654 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
@@ -27,6 +27,7 @@ import de.agilecoders.wicket.core.settings.IBootstrapSettings;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -68,6 +69,9 @@ import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Response;
import org.apache.wicket.request.component.IRequestablePage;
+import org.apache.wicket.request.cycle.IRequestCycleListener;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.http.WebResponse;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
@@ -90,7 +94,7 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
private static final String CUSTOM_FORM_ATTRIBUTES_FILE = "customFormAttributes.json";
public static final List<Locale> SUPPORTED_LOCALES = List.of(
- Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR"), new Locale("ru"), Locale.JAPANESE);
+ Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR"), new Locale("ru"), Locale.JAPANESE);
private static final ObjectMapper MAPPER = new ObjectMapper();
@@ -129,6 +133,17 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
private Map<String, CustomAttributesInfo> customFormAttributes;
+ 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));
+ }
+ }
+ }
+
private NetworkService getNetworkService() {
NetworkService ns = new NetworkService();
ns.setType(NetworkService.Type.ENDUSER);
@@ -153,9 +168,6 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
captchaEnabled = Boolean.parseBoolean(props.getProperty("captcha"));
Args.notNull(captchaEnabled, "<captcha>");
- boolean xsrf = Boolean.parseBoolean(props.getProperty("xsrf"));
- Args.notNull(xsrf, "<xsrf>");
-
useGZIPCompression = BooleanUtils.toBoolean(props.getProperty("useGZIPCompression"));
Args.notNull(useGZIPCompression, "<useGZIPCompression>");
maxUploadFileSizeMB = props.getProperty("maxUploadFileSizeMB") == null
@@ -268,10 +280,6 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
}
});
- if (xsrf) {
- getRequestCycleListeners().add(new CsrfPreventionRequestCycleListener());
- }
-
getRequestCycleListeners().add(new SyncopeUIRequestCycleListener() {
@Override
@@ -291,6 +299,19 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
});
+ if (BooleanUtils.toBoolean(props.getProperty("csrf"))) {
+ getRequestCycleListeners().add(new CsrfPreventionRequestCycleListener());
+ }
+ getRequestCycleListeners().add(new IRequestCycleListener() {
+
+ @Override
+ public void onEndRequest(final RequestCycle cycle) {
+ if (cycle.getResponse() instanceof WebResponse) {
+ setSecurityHeaders(props, (WebResponse) cycle.getResponse());
+ }
+ }
+ });
+
// Confirm password reset page
mountPage("/confirmpasswordreset", SelfConfirmPasswordReset.class);
@@ -414,5 +435,4 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
LOG.error("While extracting ext attributes", e);
}
}
-
}
diff --git a/client/idrepo/enduser/src/main/resources/enduser.properties b/client/idrepo/enduser/src/main/resources/enduser.properties
index 5adb55a..27e3053 100644
--- a/client/idrepo/enduser/src/main/resources/enduser.properties
+++ b/client/idrepo/enduser/src/main/resources/enduser.properties
@@ -23,4 +23,10 @@ useGZIPCompression=true
maxUploadFileSizeMB=5
captcha=true
-xsrf=true
+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/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login_it.properties
index e54db3c..d2fb118 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login_it.properties
@@ -18,5 +18,5 @@ username=Username
password=Password
submit=Login
login-error=Username e/o password errati
-self-registration=Registratione
+self-registration=Registrazione
self-pwd-reset=Reset Password
diff --git a/core/starter/pom.xml b/core/starter/pom.xml
index f492545..ad2baf5 100644
--- a/core/starter/pom.xml
+++ b/core/starter/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/docker/enduser/src/main/resources/enduser.properties b/docker/enduser/src/main/resources/enduser.properties
deleted file mode 100644
index 5adb55a..0000000
--- a/docker/enduser/src/main/resources/enduser.properties
+++ /dev/null
@@ -1,26 +0,0 @@
-# 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.
-enduser.directory=${conf.directory}
-
-anonymousUser=${anonymousUser}
-anonymousKey=${anonymousKey}
-adminUser=${adminUser}
-useGZIPCompression=true
-maxUploadFileSizeMB=5
-
-captcha=true
-xsrf=true
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index 1646a64..18158c5 100644
--- a/fit/build-tools/pom.xml
+++ b/fit/build-tools/pom.xml
@@ -201,21 +201,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/src/main/resources/console.properties b/fit/console-reference/src/main/resources/console.properties
index a2b3bad..0b51e78 100644
--- a/fit/console-reference/src/main/resources/console.properties
+++ b/fit/console-reference/src/main/resources/console.properties
@@ -25,8 +25,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
@@ -41,6 +39,14 @@ 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
-executor.corePoolSize=50
-executor.maxPoolSize=100
-executor.queueCapacity=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/fit/core-reference/src/test/resources/console.properties b/fit/core-reference/src/test/resources/console.properties
index 10e2d4f..0c6250c 100644
--- a/fit/core-reference/src/test/resources/console.properties
+++ b/fit/core-reference/src/test/resources/console.properties
@@ -25,8 +25,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
@@ -45,3 +43,10 @@ executor.corePoolSize=50
executor.maxPoolSize=100
executor.queueCapacity=10
+csrf=false
+
+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/src/test/resources/enduser.properties b/fit/core-reference/src/test/resources/enduser.properties
index 97a84fc..fc07dfa 100644
--- a/fit/core-reference/src/test/resources/enduser.properties
+++ b/fit/core-reference/src/test/resources/enduser.properties
@@ -22,4 +22,10 @@ adminUser=${adminUser}
useGZIPCompression=true
captcha=false
-xsrf=false
+csrf=false
+
+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/enduser-reference/src/main/resources/enduser.properties b/fit/enduser-reference/src/main/resources/enduser.properties
index 5adb55a..27e3053 100644
--- a/fit/enduser-reference/src/main/resources/enduser.properties
+++ b/fit/enduser-reference/src/main/resources/enduser.properties
@@ -23,4 +23,10 @@ useGZIPCompression=true
maxUploadFileSizeMB=5
captcha=true
-xsrf=true
+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/enduser-reference/src/test/resources/enduser.properties b/fit/enduser-reference/src/test/resources/enduser.properties
deleted file mode 100644
index 97a84fc..0000000
--- a/fit/enduser-reference/src/test/resources/enduser.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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.
-enduser.directory=${conf.directory}
-
-anonymousUser=${anonymousUser}
-anonymousKey=${anonymousKey}
-adminUser=${adminUser}
-useGZIPCompression=true
-
-captcha=false
-xsrf=false
diff --git a/pom.xml b/pom.xml
index 17685e1..ec14e66 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1500,16 +1500,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>
@@ -1788,6 +1788,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>
diff --git a/sra/pom.xml b/sra/pom.xml
index adfe9e6..db03aae 100644
--- a/sra/pom.xml
+++ b/sra/pom.xml
@@ -94,21 +94,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>