You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by al...@apache.org on 2022/02/20 23:08:54 UTC
[fineract] branch 1.6.0 updated: FINERACT-1490: SSL configuration based on application.properties
This is an automated email from the ASF dual-hosted git repository.
aleks pushed a commit to branch 1.6.0
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/1.6.0 by this push:
new 3e29d31 FINERACT-1490: SSL configuration based on application.properties
3e29d31 is described below
commit 3e29d31706951f01f0f46e366464ffbb4f03ded0
Author: Aleksandar Vidakovic <ch...@monkeysintown.com>
AuthorDate: Mon Jan 17 01:59:49 2022 +0100
FINERACT-1490: SSL configuration based on application.properties
---
README.md | 13 +++
.../org/apache/fineract/ServerApplication.java | 3 -
.../boot/EmbeddedTomcatWithSSLConfiguration.java | 112 ---------------------
.../core/config/OAuth2SecurityConfig.java | 13 ++-
.../infrastructure/core/config/SecurityConfig.java | 12 ++-
.../src/main/resources/application.properties | 18 ++++
.../EmbeddedTomcatWithSSLConfigurationTest.java | 56 -----------
.../src/test/resources/application-test.properties | 8 ++
integration-tests/build.gradle | 1 +
9 files changed, 61 insertions(+), 175 deletions(-)
diff --git a/README.md b/README.md
index 767629f..eb8ca68 100644
--- a/README.md
+++ b/README.md
@@ -186,6 +186,19 @@ Please check `application.properties` to see which connection pool settings can
NOTE: we'll keep backwards compatibility until one of the next releases to ensure that things are working as expected. Environment variables prefixed `fineract_tenants_*` can still be used to configure the database connection, but we strongly encourage using `FINERACT_HIKARI_*` with more options.
+SSL configuration
+=================
+
+By default SSL is enabled, but all SSL related properties are now tunable. SSL can be turned off by setting the environment variable `FINERACT_SERVER_SSL_ENABLED` to false. If you do that then please make sure to also change the server port to `8080` via the variable `FINERACT_SERVER_PORT`, just for the sake of keeping the conventions.
+You can choose now easily a different SSL keystore by setting `FINERACT_SERVER_SSL_KEY_STORE` with a path to a different (not embedded) keystore. The password can be set via `FINERACT_SERVER_SSL_KEY_STORE_PASSWORD`. See the `application.properties` file and the latest Spring Boot documentation (https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html) for more details.
+
+
+Tomcat configuration
+====================
+
+Please refer to the `application.properties` and the official Spring Boot documentation (https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html) on how to do performance tuning for Tomcat. Note: you can set now the acceptable form POST size (default is 2MB) via environment variable `FINERACT_SERVER_TOMCAT_MAX_HTTP_FORM_POST_SIZE`.
+
+
Instructions to run on Kubernetes
=================================
diff --git a/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java b/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java
index e206351..f567a6c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/ServerApplication.java
@@ -20,12 +20,10 @@ package org.apache.fineract;
import java.io.IOException;
import org.apache.fineract.infrastructure.core.boot.AbstractApplicationConfiguration;
-import org.apache.fineract.infrastructure.core.boot.EmbeddedTomcatWithSSLConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.annotation.Import;
/**
* Fineract main() application which launches Fineract in an embedded Tomcat HTTP (using Spring Boot).
@@ -42,7 +40,6 @@ import org.springframework.context.annotation.Import;
public class ServerApplication extends SpringBootServletInitializer {
- @Import({ EmbeddedTomcatWithSSLConfiguration.class })
private static class Configuration extends AbstractApplicationConfiguration {}
@Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/EmbeddedTomcatWithSSLConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/EmbeddedTomcatWithSSLConfiguration.java
deleted file mode 100644
index 8f5d26c..0000000
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/EmbeddedTomcatWithSSLConfiguration.java
+++ /dev/null
@@ -1,112 +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.
- */
-package org.apache.fineract.infrastructure.core.boot;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import org.apache.catalina.connector.Connector;
-import org.apache.commons.io.FileUtils;
-import org.apache.coyote.http11.Http11NioProtocol;
-import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
-import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-
-@Configuration
-public class EmbeddedTomcatWithSSLConfiguration {
-
- // https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/html/howto.html#howto-enable-multiple-connectors-in-tomcat
-
- @Bean
- public ServletWebServerFactory servletContainer() {
- TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
- tomcat.setContextPath(getContextPath());
- tomcat.addAdditionalTomcatConnectors(createSslConnector());
- return tomcat;
- }
-
- private String getContextPath() {
- return "/fineract-provider";
- }
-
- protected Connector createSslConnector() {
- Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
- Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
- try {
- File keystore = getFile(getKeystore());
- connector.setScheme("https");
- connector.setSecure(true);
- connector.setPort(getHTTPSPort());
- protocol.setSSLEnabled(true);
- protocol.setKeystoreFile(keystore.getAbsolutePath());
- protocol.setKeystorePass(getKeystorePass());
- return connector;
- } catch (IOException ex) {
- throw new IllegalStateException("can't access keystore: [" + "keystore" + "] or truststore: [" + "keystore" + "]", ex);
- }
- }
-
- protected int getHTTPSPort() {
- // TODO This shouldn't be hard-coded here, but configurable
- return 8443;
- }
-
- protected String getKeystorePass() {
- return "openmf";
- }
-
- protected Resource getKeystore() {
- return new ClassPathResource("/keystore.jks");
- }
-
- public File getFile(Resource resource) throws IOException {
- try {
- return resource.getFile();
- } catch (IOException e) {
- // Uops.. OK, try again (below)
- }
-
- try {
- URL url = resource.getURL();
- /**
- * // If this creates filenames that are too long on Win, // then could just use resource.getFilename(), //
- * even though not unique, real risk prob. min.bon String tempDir = System.getProperty("java.io.tmpdir");
- * tempDir = tempDir + "/" + getClass().getSimpleName() + "/"; String path = url.getPath(); String uniqName
- * = path.replace("file:/", "").replace('!', '_'); String tempFullPath = tempDir + uniqName;
- **/
- // instead of File.createTempFile(prefix?, suffix?);
- File targetFile = new File(resource.getFilename());
- long len = resource.contentLength();
- if (!targetFile.exists() || targetFile.length() != len) { // Only
- // copy
- // new
- // files
- FileUtils.copyURLToFile(url, targetFile);
- }
- return targetFile;
- } catch (IOException e) {
- // Uops.. erm, give up:
- throw new IOException("Cannot obtain a File for Resource: " + resource.toString(), e);
- }
-
- }
-}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/OAuth2SecurityConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/OAuth2SecurityConfig.java
index 32202a6..6266d1e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/OAuth2SecurityConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/OAuth2SecurityConfig.java
@@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatfor
import org.apache.fineract.infrastructure.security.vote.SelfServiceUserAccessVote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -72,6 +73,9 @@ public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private TenantAwareJpaPlatformUserDetailsService userDetailsService;
+ @Autowired
+ private ServerProperties serverProperties;
+
private static final JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
@Override
@@ -97,8 +101,13 @@ public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) //
.and() //
.addFilterAfter(tenantAwareTenantIdentifierFilter, SecurityContextPersistenceFilter.class) //
- .addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class) //
- .requiresChannel(channel -> channel.antMatchers("/api/**").requiresSecure());
+ .addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class); //
+
+ if (serverProperties.getSsl().isEnabled()) {
+ http.requiresChannel(channel -> channel.antMatchers("/api/**").requiresSecure());
+ } else {
+ http.requiresChannel(channel -> channel.antMatchers("/api/**").requiresInsecure());
+ }
}
@Bean
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java
index 8fac767..ed9dce5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java
@@ -24,6 +24,7 @@ import org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticatio
import org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatformUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -52,6 +53,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private TwoFactorAuthenticationFilter twoFactorAuthenticationFilter;
+ @Autowired
+ private ServerProperties serverProperties;
+
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -74,9 +78,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) //
.and() //
.addFilterAfter(tenantAwareBasicAuthenticationFilter(), SecurityContextPersistenceFilter.class) //
- .addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class) //
- .requiresChannel(channel -> channel.antMatchers("/api/**").requiresSecure());
+ .addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class); //
+ if (serverProperties.getSsl().isEnabled()) {
+ http.requiresChannel(channel -> channel.antMatchers("/api/**").requiresSecure());
+ } else {
+ http.requiresChannel(channel -> channel.antMatchers("/api/**").requiresInsecure());
+ }
}
@Bean
diff --git a/fineract-provider/src/main/resources/application.properties b/fineract-provider/src/main/resources/application.properties
index 92b6f4e..bbb251d 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -46,6 +46,24 @@ management.endpoints.web.exposure.include=health,info
# FINERACT-914
server.forward-headers-strategy=framework
+server.port=${FINERACT_SERVER_PORT:8443}
+server.servlet.context-path=${FINERACT_SERVER_SERVLET_CONTEXT_PATH:/fineract-provider}
+server.compression.enabled=${FINERACT_SERVER_COMPRESSION_ENABLED:true}
+
+server.ssl.enabled=${FINERACT_SERVER_SSL_ENABLED:true}
+server.ssl.protocol=TLS
+#server.ssl.ciphers=${FINERACT_SERVER_SSL_CIPHERS:TLS_RSA_WITH_AES_128_CBC_SHA256}
+#server.ssl.enabled-protocols=${FINERACT_SERVER_SSL_PROTOCOLS:TLSv1.2}
+server.ssl.key-store=${FINERACT_SERVER_SSL_KEY_STORE:classpath:keystore.jks}
+server.ssl.key-store-password=${FINERACT_SERVER_SSL_KEY_STORE_PASSWORD:openmf}
+
+server.tomcat.accept-count=${FINERACT_SERVER_TOMCAT_ACCEPT_COUNT:100}
+server.tomcat.accesslog.enabled=${FINERACT_SERVER_TOMCAT_ACCESSLOG_ENABLED:false}
+server.tomcat.max-connections=${FINERACT_SERVER_TOMCAT_MAX_CONNECTIONS:8192}
+server.tomcat.max-http-form-post-size=${FINERACT_SERVER_TOMCAT_MAX_HTTP_FORM_POST_SIZE:2MB}
+server.tomcat.max-keep-alive-requests=${FINERACT_SERVER_TOMCAT_MAX_KEEP_ALIVE_REQUESTS:100}
+server.tomcat.threads.max=${FINERACT_SERVER_TOMCAT_THREADS_MAX:200}
+server.tomcat.threads.min-spare=${FINERACT_SERVER_TOMCAT_THREADS_MIN_SPARE:10}
# OAuth authorisation server endpoint
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:9000/auth/realms/fineract
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/boot/tests/EmbeddedTomcatWithSSLConfigurationTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/boot/tests/EmbeddedTomcatWithSSLConfigurationTest.java
deleted file mode 100644
index b16f7d3..0000000
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/boot/tests/EmbeddedTomcatWithSSLConfigurationTest.java
+++ /dev/null
@@ -1,56 +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.
- */
-package org.apache.fineract.infrastructure.core.boot.tests;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.fineract.infrastructure.core.boot.EmbeddedTomcatWithSSLConfiguration;
-import org.junit.jupiter.api.Test;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-
-public class EmbeddedTomcatWithSSLConfigurationTest {
-
- @Test
- public void testGetFileWithFileResource() throws IOException {
- // Test class probably isn't in a JAR
- checkClassResource(getClass());
- }
-
- @Test
- public void testGetFileWithClasspathResource() throws IOException {
- // Spring Resource class probably is in a JAR
- File f1 = checkClassResource(Resource.class);
- f1.delete();
- checkClassResource(Resource.class);
- }
-
- protected File checkClassResource(Class<?> clazz) throws IOException {
- String testClasspathResourcePath = clazz.getCanonicalName().replace('.', '/') + ".class";
- Resource r = new ClassPathResource(testClasspathResourcePath);
- File f = new EmbeddedTomcatWithSSLConfiguration().getFile(r);
- assertTrue(f.exists());
- f = new EmbeddedTomcatWithSSLConfiguration().getFile(r);
- assertTrue(f.exists());
- return f;
- }
-}
diff --git a/fineract-provider/src/test/resources/application-test.properties b/fineract-provider/src/test/resources/application-test.properties
index 6a6f765..b778947 100644
--- a/fineract-provider/src/test/resources/application-test.properties
+++ b/fineract-provider/src/test/resources/application-test.properties
@@ -46,6 +46,14 @@ management.endpoints.web.exposure.include=health,info
# FINERACT-914
server.forward-headers-strategy=framework
+server.port=8443
+server.servlet.context-path=/fineract-provider
+server.compression.enabled=true
+
+server.ssl.enabled=true
+server.ssl.protocol=TLS
+server.ssl.key-store=keystore.jks
+server.ssl.key-store-password=openmf
spring.datasource.hikari.driverClassName=org.mariadb.jdbc.Driver
spring.datasource.hikari.jdbcUrl=jdbc:mariadb://localhost:3306/fineract_tenants
diff --git a/integration-tests/build.gradle b/integration-tests/build.gradle
index 3590869..4d4cfb8 100644
--- a/integration-tests/build.gradle
+++ b/integration-tests/build.gradle
@@ -38,6 +38,7 @@ cargo {
}
local {
+ logLevel = 'medium'
installer {
installConfiguration = configurations.tomcat
downloadDir = file("$buildDir/download")