This is an automated email from the ASF dual-hosted git repository.
ptuomola pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 907f932 Simplify build for different auth strategies
907f932 is described below
commit 907f932abe5bd13a87052e7179ca3394560b57ee
Author: Aleksandar Vidakovic <[email protected]>
AuthorDate: Sun Jan 2 05:07:20 2022 +0100
Simplify build for different auth strategies
---
.github/workflows/build-oauth2.yml | 60 ----------------------
.github/workflows/build-twofactor.yml | 52 -------------------
.github/workflows/build.yml | 22 ++++++--
.gitignore | 1 -
README.md | 44 ++++++++++++++++
fineract-provider/build.gradle | 32 ------------
.../properties/basicauth/application.properties | 33 ------------
.../properties/oauth/application.properties | 37 -------------
.../core/config/OAuth2SecurityConfig.java | 4 +-
.../infrastructure/core/config/SecurityConfig.java | 4 +-
.../core/config/SecurityValidationConfig.java | 50 ++++++++++++++++++
.../security/api/AuthenticationApiResource.java | 15 +++---
.../security/api/TwoFactorApiResource.java | 4 +-
.../api/TwoFactorConfigurationApiResource.java | 4 +-
.../security/api/UserDetailsApiResource.java | 21 ++++----
.../InvalidateTFAccessTokenCommandHandler.java | 4 +-
.../UpdateTwoFactorConfigCommandHandler.java | 4 +-
.../data/TwoFactorConfigurationValidator.java | 4 +-
.../security/domain/OTPRequestRepository.java | 4 +-
.../security/domain/TFAccessTokenRepository.java | 4 +-
.../domain/TwoFactorConfigurationRepository.java | 4 +-
.../InsecureTwoFactorAuthenticationFilter.java | 4 +-
.../TenantAwareBasicAuthenticationFilter.java | 4 +-
.../filter/TenantAwareTenantIdentifierFilter.java | 4 +-
.../filter/TwoFactorAuthenticationFilter.java | 4 +-
.../service/TwoFactorConfigurationServiceImpl.java | 4 +-
.../security/service/TwoFactorServiceImpl.java | 4 +-
.../security/service/TwoFactorUtils.java | 45 ----------------
.../api/SelfAuthenticationApiResource.java | 4 +-
.../security/api/SelfUserDetailsApiResource.java | 4 +-
.../main/resources}/application.properties | 8 +--
.../provider/CommandHandlerProviderTest.java | 4 +-
.../spring/SpringConfigurationTest.java | 4 +-
...TestsWithoutDatabaseAndNoJobsConfiguration.java | 9 ++++
...ractSpringBootWithMariaDB4jIntegrationTest.java | 4 +-
.../test/resources/application-test.properties} | 6 ++-
oauth2-tests/build.gradle | 2 +-
twofactor-tests/build.gradle | 2 +-
.../TwoFactorAuthenticationTest.java | 2 +-
39 files changed, 194 insertions(+), 331 deletions(-)
diff --git a/.github/workflows/build-oauth2.yml
b/.github/workflows/build-oauth2.yml
deleted file mode 100644
index 7b715fe..0000000
--- a/.github/workflows/build-oauth2.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-name: Fineract Gradle build - oauth2
-on: [push, pull_request]
-
-jobs:
- build:
- runs-on: ubuntu-20.04
-
- services:
- mariad:
- image: mariadb:10.6
- ports:
- - 3306:3306
- env:
- MARIADB_ROOT_PASSWORD: mysql
- options: --health-cmd="mysqladmin ping" --health-interval=5s
--health-timeout=2s --health-retries=3
-
- mock-oauth2-server:
- image: ghcr.io/navikt/mock-oauth2-server:0.4.0
- ports:
- - 9000:9000
- env:
- SERVER_PORT: 9000
- JSON_CONFIG: '{ "interactiveLogin": true, "httpServer":
"NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract",
"tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match":
"fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
-
- env:
- TZ: Asia/Kolkata
- steps:
- - name: Set up cache
- uses: actions/cache@v2
- with:
- path: |
- ~/.gradle/caches
- ~/.gradle/wrapper
- key: ${{ runner.os }}-gradle-oauth2-${{ hashFiles('**/*.gradle*',
'**/gradle-wrapper.properties') }}
- restore-keys: |
- ${{ runner.os }}-gradle-oauth2-
- - name: Checkout
- uses: actions/checkout@v2
- - name: Set up JDK 11
- uses: actions/setup-java@v2
- with:
- java-version: '11'
- distribution: 'zulu'
- - name: Validate Gradle wrapper
- uses:
gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- - name: Verify MariaDB connection
- run: |
- while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
- sleep 1
- done
- - name: Initialise databases
- run: |
- ./gradlew --no-daemon -q createDB -PdbName=fineract_tenants
- ./gradlew --no-daemon -q createDB -PdbName=fineract_default
- - name: Install additional software
- run: |
- sudo apt-get update
- sudo apt-get install ghostscript -y
- - name: Build & Test
- run: ./gradlew --no-daemon -q --console=plain build test --fail-fast
-x :integration-tests:test -x :twofactor-tests:test -Psecurity=oauth
diff --git a/.github/workflows/build-twofactor.yml
b/.github/workflows/build-twofactor.yml
deleted file mode 100644
index aac7141..0000000
--- a/.github/workflows/build-twofactor.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-name: Fineract Gradle build - twofactor
-on: [push, pull_request]
-
-jobs:
- build:
- runs-on: ubuntu-20.04
-
- services:
- mariad:
- image: mariadb:10.6
- ports:
- - 3306:3306
- env:
- MARIADB_ROOT_PASSWORD: mysql
- options: --health-cmd="mysqladmin ping" --health-interval=5s
--health-timeout=2s --health-retries=3
-
- env:
- TZ: Asia/Kolkata
- steps:
- - name: Set up cache
- uses: actions/cache@v2
- with:
- path: |
- ~/.gradle/caches
- ~/.gradle/wrapper
- key: ${{ runner.os }}-gradle-twofactor-${{ hashFiles('**/*.gradle*',
'**/gradle-wrapper.properties') }}
- restore-keys: |
- ${{ runner.os }}-gradle-twofactor-
- - name: Checkout
- uses: actions/checkout@v2
- - name: Set up JDK 11
- uses: actions/setup-java@v2
- with:
- java-version: '11'
- distribution: 'zulu'
- - name: Validate Gradle wrapper
- uses:
gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- - name: Verify MariaDB connection
- run: |
- while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
- sleep 1
- done
- - name: Initialise databases
- run: |
- ./gradlew --no-daemon -q createDB -PdbName=fineract_tenants
- ./gradlew --no-daemon -q createDB -PdbName=fineract_default
- - name: Install additional software
- run: |
- sudo apt-get update
- sudo apt-get install ghostscript -y
- - name: Build & Test
- run: ./gradlew --no-daemon -q --console=plain build test --fail-fast
-x :integration-tests:test -x :oauth2-tests:test -Ptwofactor=enabled
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9e89ac6..6ce6f08 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -13,6 +13,15 @@ jobs:
env:
MARIADB_ROOT_PASSWORD: mysql
options: --health-cmd="mysqladmin ping" --health-interval=5s
--health-timeout=2s --health-retries=3
+
+ mock-oauth2-server:
+ image: ghcr.io/navikt/mock-oauth2-server:0.4.0
+ ports:
+ - 9000:9000
+ env:
+ SERVER_PORT: 9000
+ JSON_CONFIG: '{ "interactiveLogin": true, "httpServer":
"NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract",
"tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match":
"fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
+
env:
TZ: Asia/Kolkata
steps:
@@ -22,9 +31,9 @@ jobs:
path: |
~/.gradle/caches
~/.gradle/wrapper
- key: ${{ runner.os }}-gradle-basicauth-${{ hashFiles('**/*.gradle*',
'**/gradle-wrapper.properties') }}
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*',
'**/gradle-wrapper.properties') }}
restore-keys: |
- ${{ runner.os }}-gradle-basicauth-
+ ${{ runner.os }}-gradle-
- name: Checkout
uses: actions/checkout@v2
- name: Set up JDK 11
@@ -47,5 +56,12 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install ghostscript -y
- - name: Build & Test
+
+ - name: Basic Auth Build & Test
run: ./gradlew --no-daemon -q --console=plain licenseMain licenseTest
check build test --fail-fast doc -x :twofactor-tests:test -x :oauth2-test:test
+
+ - name: 2FA Build & Test
+ run: ./gradlew --no-daemon -q --console=plain :twofactor-tests:test
--fail-fast
+
+ - name: OAuth2 Build & Test
+ run: ./gradlew --no-daemon -q --console=plain :oauth2-tests:test
--fail-fast
diff --git a/.gitignore b/.gitignore
index e56ba7e..0ae3f43 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,6 @@ build
catalina.base_IS_UNDEFINED/
keystore.jks
bin/
-fineract-provider/src/main/resources/application.properties
.lock
fineract-provider/out/
fineract-provider/config/swagger/config.json
diff --git a/README.md b/README.md
index d276d3e..9c26e58 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,50 @@ The tenants database connection details are configured [via
environment variable
java -jar fineract-provider.jar
+Security
+============
+NOTE: The HTTP Basic and OAuth2 authentication schemes are mutually exclusive.
You can't enable them both at the same time. Fineract checks these settings on
startup and will fail if more than one authentication scheme is enabled.
+
+HTTP Basic Authentication
+------------
+By default Fineract is configured with a HTTP Basic Authentication scheme, so
you actually don't have to do anything if you want to use it. But if you would
like to explicitly choose this authentication scheme then there are two ways to
enable it:
+1. Use environment variables (best choice if you run with Docker Compose):
+```
+FINERACT_SECURITY_BASICAUTH_ENABLED=true
+FINERACT_SECURITY_OAUTH_ENABLED=false
+```
+2. Use JVM parameters (best choice if you run the Spring Boot JAR):
+```
+java -Dfineract.security.basicauth.enabled=true
-Dfineract.security.oauth.enabled=false -jar fineract-provider.jar
+```
+
+OAuth2 Authentication
+------------
+There is also an OAuth2 authentication scheme available. Again, two ways to
enable it:
+1. Use environment variables (best choice if you run with Docker Compose):
+```
+FINERACT_SECURITY_BASICAUTH_ENABLED=false
+FINERACT_SECURITY_OAUTH_ENABLED=true
+```
+2. Use JVM parameters (best choice if you run the Spring Boot JAR):
+```
+java -Dfineract.security.basicauth.enabled=false
-Dfineract.security.oauth.enabled=true -jar fineract-provider.jar
+```
+
+Two Factor Authentication
+------------
+You can also enable 2FA authentication. Depending on how you start Fineract
add the following:
+
+1. Use environment variable (best choice if you run with Docker Compose):
+```
+FINERACT_SECURITY_2FA_ENABLED=true
+```
+2. Use JVM parameter (best choice if you run the Spring Boot JAR):
+```
+-Dfineract.security.2fa.enabled=true
+```
+
+
Instructions to build a WAR file
============
1. Clone the repository or download and extract the archive file to your local
directory.
diff --git a/fineract-provider/build.gradle b/fineract-provider/build.gradle
index f034777..0d8d44a 100644
--- a/fineract-provider/build.gradle
+++ b/fineract-provider/build.gradle
@@ -155,37 +155,6 @@ configurations {
apply from: 'dependencies.gradle'
-/* Enable Oauth2 authentication based on environment, default to HTTP basic
auth */
-if (project.hasProperty('security') && project.getProperty('security') ==
'oauth') {
- if(project.hasProperty('twofactor') && project.getProperty('twofactor') ==
'enabled') {
- copy {
- from './properties/oauth/twofactor/'
- into 'src/main/resources/'
- include '*.properties'
- }
- } else {
- copy {
- from './properties/oauth/'
- into 'src/main/resources/'
- include '*.properties'
- }
- }
-} else {
- if(project.hasProperty('twofactor') && project.getProperty('twofactor') ==
'enabled') {
- copy {
- from './properties/basicauth/twofactor/'
- into 'src/main/resources/'
- include '*.properties'
- }
- } else {
- copy {
- from './properties/basicauth/'
- into 'src/main/resources/'
- include '*.properties'
- }
- }
-}
-
// Configuration for the modernizer plugin
// https://github.com/andygoossens/gradle-modernizer-plugin
modernizer {
@@ -324,7 +293,6 @@ jib {
]
args = [
'-Duser.home=/tmp',
- '-Dspring.profiles.active=basicauth',
'-Dfile.encoding=UTF-8',
'-Duser.timezone=UTC',
'-Djava.security.egd=file:/dev/./urandom'
diff --git a/fineract-provider/properties/basicauth/application.properties
b/fineract-provider/properties/basicauth/application.properties
deleted file mode 100644
index be392eb..0000000
--- a/fineract-provider/properties/basicauth/application.properties
+++ /dev/null
@@ -1,33 +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.
-#
-
-spring.profiles.default=basicauth
-management.health.jms.enabled=false
-
-# FINERACT 1296
-management.endpoint.health.probes.enabled=true
-management.health.livenessState.enabled=true
-management.health.readinessState.enabled=true
-
-# FINERACT-883
-management.info.git.mode=FULL
-management.endpoints.web.exposure.include=health,info
-
-# FINERACT-914
-server.forward-headers-strategy=framework
diff --git a/fineract-provider/properties/oauth/application.properties
b/fineract-provider/properties/oauth/application.properties
deleted file mode 100644
index 6936db5..0000000
--- a/fineract-provider/properties/oauth/application.properties
+++ /dev/null
@@ -1,37 +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.
-#
-
-spring.profiles.default=basicauth
-spring.profiles.active=oauth
-management.health.jms.enabled=false
-
-# FINERACT 1296
-management.endpoint.health.probes.enabled=true
-management.health.livenessState.enabled=true
-management.health.readinessState.enabled=true
-
-# FINERACT-883
-management.info.git.mode=FULL
-management.endpoints.web.exposure.include=health,info
-
-# FINERACT-914
-server.forward-headers-strategy=framework
-
-# OAuth authorisation server endpoint
-spring.security.oauth2.resourceserver.jwt.issuer-uri:
http://localhost:9000/auth/realms/fineract
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 a2226c9..32202a6 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
@@ -29,10 +29,10 @@ import
org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticatio
import
org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatformUserDetailsService;
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.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.AccessDecisionManager;
@@ -59,7 +59,7 @@ import
org.springframework.security.web.authentication.www.BasicAuthenticationFi
import
org.springframework.security.web.context.SecurityContextPersistenceFilter;
@Configuration
-@Profile("oauth")
+@ConditionalOnProperty("fineract.security.oauth.enabled")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
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 4269790..8fac767 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
@@ -23,10 +23,10 @@ import
org.apache.fineract.infrastructure.security.filter.TenantAwareBasicAuthen
import
org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticationFilter;
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.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import
org.springframework.security.authentication.dao.DaoAuthenticationProvider;
@@ -42,7 +42,7 @@ import
org.springframework.security.web.authentication.www.BasicAuthenticationFi
import
org.springframework.security.web.context.SecurityContextPersistenceFilter;
@Configuration
-@Profile("basicauth")
+@ConditionalOnProperty("fineract.security.basicauth.enabled")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityValidationConfig.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityValidationConfig.java
new file mode 100644
index 0000000..6954d46
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityValidationConfig.java
@@ -0,0 +1,50 @@
+/**
+ * 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.config;
+
+import javax.annotation.PostConstruct;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SecurityValidationConfig {
+
+ @Value("${fineract.security.basicauth.enabled}")
+ private Boolean basicAuthEnabled;
+
+ @Value("${fineract.security.oauth.enabled}")
+ private Boolean oauthEnabled;
+
+ @PostConstruct
+ public void validate() {
+ // NOTE: avoid NPE if these values are not set
+ if (!Boolean.TRUE.equals(basicAuthEnabled) &&
!Boolean.TRUE.equals(oauthEnabled)) {
+ // NOTE: while we are already doing consistency checks we might as
well cover this case; should not happen
+ // as defaults are set in application.properties
+ throw new IllegalArgumentException(
+ "No authentication scheme selected. Please decide if you
want to use basic OR OAuth2 authentication.");
+ }
+
+ if (Boolean.TRUE.equals(basicAuthEnabled) &&
Boolean.TRUE.equals(oauthEnabled)) {
+ throw new IllegalArgumentException(
+ "Too many authentication schemes selected. Please decide
if you want to use basic OR OAuth2 authentication.");
+ }
+ }
+}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
index fc3ed60..91efd8e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
@@ -44,14 +44,14 @@ import
org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer
import
org.apache.fineract.infrastructure.security.constants.TwoFactorConstants;
import org.apache.fineract.infrastructure.security.data.AuthenticatedUserData;
import
org.apache.fineract.infrastructure.security.service.SpringSecurityPlatformSecurityContext;
-import org.apache.fineract.infrastructure.security.service.TwoFactorUtils;
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
import org.apache.fineract.useradministration.data.RoleData;
import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.fineract.useradministration.domain.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Profile;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import
org.springframework.security.authentication.dao.DaoAuthenticationProvider;
@@ -61,11 +61,14 @@ import org.springframework.stereotype.Component;
@Component
@Scope("singleton")
-@Profile("basicauth")
+@ConditionalOnProperty("fineract.security.basicauth.enabled")
@Path("/authentication")
@Tag(name = "Authentication HTTP Basic", description = "An API capability that
allows client applications to verify authentication details using HTTP Basic
Authentication.")
public class AuthenticationApiResource {
+ @Value("${fineract.security.2fa.enabled}")
+ private boolean twoFactorEnabled;
+
public static class AuthenticateRequest {
public String username;
@@ -75,19 +78,17 @@ public class AuthenticationApiResource {
private final DaoAuthenticationProvider customAuthenticationProvider;
private final ToApiJsonSerializer<AuthenticatedUserData>
apiJsonSerializerService;
private final SpringSecurityPlatformSecurityContext
springSecurityPlatformSecurityContext;
- private final TwoFactorUtils twoFactorUtils;
private final ClientReadPlatformService clientReadPlatformService;
@Autowired
public AuthenticationApiResource(
@Qualifier("customAuthenticationProvider") final
DaoAuthenticationProvider customAuthenticationProvider,
final ToApiJsonSerializer<AuthenticatedUserData>
apiJsonSerializerService,
- final SpringSecurityPlatformSecurityContext
springSecurityPlatformSecurityContext, TwoFactorUtils twoFactorUtils,
+ final SpringSecurityPlatformSecurityContext
springSecurityPlatformSecurityContext,
ClientReadPlatformService aClientReadPlatformService) {
this.customAuthenticationProvider = customAuthenticationProvider;
this.apiJsonSerializerService = apiJsonSerializerService;
this.springSecurityPlatformSecurityContext =
springSecurityPlatformSecurityContext;
- this.twoFactorUtils = twoFactorUtils;
clientReadPlatformService = aClientReadPlatformService;
}
@@ -143,7 +144,7 @@ public class AuthenticationApiResource {
final EnumOptionData organisationalRole =
principal.organisationalRoleData();
- boolean isTwoFactorRequired =
twoFactorUtils.isTwoFactorAuthEnabled()
+ boolean isTwoFactorRequired = this.twoFactorEnabled
&&
!principal.hasSpecificPermissionTo(TwoFactorConstants.BYPASS_TWO_FACTOR_PERMISSION);
Long userId = principal.getId();
if
(this.springSecurityPlatformSecurityContext.doesPasswordHasToBeRenewed(principal))
{
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorApiResource.java
index 839c050..91617dd 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorApiResource.java
@@ -45,13 +45,13 @@ import
org.apache.fineract.infrastructure.security.service.PlatformSecurityConte
import org.apache.fineract.infrastructure.security.service.TwoFactorService;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/twofactor")
@Component
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
@Scope("singleton")
@Tag(name = "Two Factor", description = "")
public class TwoFactorApiResource {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorConfigurationApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorConfigurationApiResource.java
index c6980eb..e76af9a 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorConfigurationApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/TwoFactorConfigurationApiResource.java
@@ -33,7 +33,7 @@ import
org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSer
import
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import
org.apache.fineract.infrastructure.security.service.TwoFactorConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -42,7 +42,7 @@ import org.springframework.stereotype.Component;
@Produces({ MediaType.APPLICATION_JSON })
@Component
@Scope("singleton")
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public class TwoFactorConfigurationApiResource {
private final String resourceNameForPermissions = "TWOFACTOR_CONFIG";
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/UserDetailsApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/UserDetailsApiResource.java
index 64e96bf..2ee5fcc 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/UserDetailsApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/UserDetailsApiResource.java
@@ -37,12 +37,12 @@ import
org.apache.fineract.infrastructure.security.constants.TwoFactorConstants;
import
org.apache.fineract.infrastructure.security.data.AuthenticatedOauthUserData;
import
org.apache.fineract.infrastructure.security.data.FineractJwtAuthenticationToken;
import
org.apache.fineract.infrastructure.security.service.SpringSecurityPlatformSecurityContext;
-import org.apache.fineract.infrastructure.security.service.TwoFactorUtils;
import org.apache.fineract.useradministration.data.RoleData;
import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.fineract.useradministration.domain.Role;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
@@ -54,22 +54,22 @@ import org.springframework.stereotype.Component;
*/
@Path("/userdetails")
@Component
-@Profile("oauth")
+@ConditionalOnProperty("fineract.security.oauth.enabled")
@Scope("singleton")
-
@Tag(name = "Fetch authenticated user details", description = "")
public class UserDetailsApiResource {
private final ToApiJsonSerializer<AuthenticatedOauthUserData>
apiJsonSerializerService;
private final SpringSecurityPlatformSecurityContext
springSecurityPlatformSecurityContext;
- private final TwoFactorUtils twoFactorUtils;
+
+ @Value("${fineract.security.2fa.enabled}")
+ private boolean twoFactorEnabled;
@Autowired
public UserDetailsApiResource(final
ToApiJsonSerializer<AuthenticatedOauthUserData> apiJsonSerializerService,
- final SpringSecurityPlatformSecurityContext
springSecurityPlatformSecurityContext, final TwoFactorUtils twoFactorUtils) {
+ final SpringSecurityPlatformSecurityContext
springSecurityPlatformSecurityContext) {
this.apiJsonSerializerService = apiJsonSerializerService;
this.springSecurityPlatformSecurityContext =
springSecurityPlatformSecurityContext;
- this.twoFactorUtils = twoFactorUtils;
}
@GET
@@ -116,16 +116,15 @@ public class UserDetailsApiResource {
final EnumOptionData organisationalRole =
principal.organisationalRoleData();
- final boolean requireTwoFactorAuth =
twoFactorUtils.isTwoFactorAuthEnabled()
+ boolean isTwoFactorRequired = this.twoFactorEnabled
&&
!principal.hasSpecificPermissionTo(TwoFactorConstants.BYPASS_TWO_FACTOR_PERMISSION);
-
if
(this.springSecurityPlatformSecurityContext.doesPasswordHasToBeRenewed(principal))
{
authenticatedUserData = new
AuthenticatedOauthUserData(principal.getUsername(), principal.getId(),
- authentication.getToken().getTokenValue(),
requireTwoFactorAuth);
+ authentication.getToken().getTokenValue(),
isTwoFactorRequired);
} else {
authenticatedUserData = new
AuthenticatedOauthUserData(principal.getUsername(), officeId, officeName,
staffId, staffDisplayName,
organisationalRole, roles, permissions, principal.getId(),
authentication.getToken().getTokenValue(),
- requireTwoFactorAuth);
+ isTwoFactorRequired);
}
return this.apiJsonSerializerService.serialize(authenticatedUserData);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/InvalidateTFAccessTokenCommandHandler.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/InvalidateTFAccessTokenCommandHandler.java
index 903b5cf..46c8062 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/InvalidateTFAccessTokenCommandHandler.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/InvalidateTFAccessTokenCommandHandler.java
@@ -43,13 +43,13 @@ import
org.apache.fineract.infrastructure.security.service.PlatformSecurityConte
import org.apache.fineract.infrastructure.security.service.TwoFactorService;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "TWOFACTOR_ACCESSTOKEN", action = "INVALIDATE")
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public class InvalidateTFAccessTokenCommandHandler implements
NewCommandSourceHandler {
private final TwoFactorService twoFactorService;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/UpdateTwoFactorConfigCommandHandler.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/UpdateTwoFactorConfigCommandHandler.java
index 58b027b..d103315 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/UpdateTwoFactorConfigCommandHandler.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/command/UpdateTwoFactorConfigCommandHandler.java
@@ -27,13 +27,13 @@ import
org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuild
import
org.apache.fineract.infrastructure.security.data.TwoFactorConfigurationValidator;
import
org.apache.fineract.infrastructure.security.service.TwoFactorConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "TWOFACTOR_CONFIGURATION", action = "UPDATE")
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public class UpdateTwoFactorConfigCommandHandler implements
NewCommandSourceHandler {
private final TwoFactorConfigurationService configurationService;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/data/TwoFactorConfigurationValidator.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/data/TwoFactorConfigurationValidator.java
index bea4599..6888a7e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/data/TwoFactorConfigurationValidator.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/data/TwoFactorConfigurationValidator.java
@@ -32,11 +32,11 @@ import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import
org.apache.fineract.infrastructure.security.constants.TwoFactorConfigurationConstants;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public class TwoFactorConfigurationValidator {
private final FromJsonHelper fromJsonHelper;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/OTPRequestRepository.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/OTPRequestRepository.java
index 031ac0f..eaf3f43 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/OTPRequestRepository.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/OTPRequestRepository.java
@@ -21,12 +21,12 @@ package org.apache.fineract.infrastructure.security.domain;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.fineract.infrastructure.security.data.OTPRequest;
import org.apache.fineract.useradministration.domain.AppUser;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;
@Repository
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
@SuppressWarnings({ "MemberName" })
public class OTPRequestRepository {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TFAccessTokenRepository.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TFAccessTokenRepository.java
index b840eae..aaed99f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TFAccessTokenRepository.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TFAccessTokenRepository.java
@@ -19,11 +19,11 @@
package org.apache.fineract.infrastructure.security.domain;
import org.apache.fineract.useradministration.domain.AppUser;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public interface TFAccessTokenRepository extends JpaRepository<TFAccessToken,
Long>, JpaSpecificationExecutor<TFAccessToken> {
TFAccessToken findByUserAndToken(AppUser user, String token);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TwoFactorConfigurationRepository.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TwoFactorConfigurationRepository.java
index 508e9a8..9692d39 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TwoFactorConfigurationRepository.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/domain/TwoFactorConfigurationRepository.java
@@ -19,11 +19,11 @@
package org.apache.fineract.infrastructure.security.domain;
import java.util.List;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public interface TwoFactorConfigurationRepository
extends JpaRepository<TwoFactorConfiguration, Long>,
JpaSpecificationExecutor<TwoFactorConfiguration> {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/InsecureTwoFactorAuthenticationFilter.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/InsecureTwoFactorAuthenticationFilter.java
index 64e40b8..0de5651 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/InsecureTwoFactorAuthenticationFilter.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/InsecureTwoFactorAuthenticationFilter.java
@@ -27,7 +27,7 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import
org.apache.fineract.infrastructure.security.data.FineractJwtAuthenticationToken;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
@@ -43,7 +43,7 @@ import org.springframework.stereotype.Service;
* This filter adds 'TWOFACTOR_AUTHENTICATED' authority to every authenticated
platform user.
*/
@Service
-@Profile("!twofactor")
+@ConditionalOnProperty(name = "fineract.security.2fa.enabled", havingValue =
"false")
public class InsecureTwoFactorAuthenticationFilter extends
TwoFactorAuthenticationFilter {
public InsecureTwoFactorAuthenticationFilter() {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
index b97c3b0..c29fbdb 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
@@ -38,7 +38,7 @@ import org.apache.fineract.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
@@ -59,7 +59,7 @@ import
org.springframework.security.web.authentication.www.BasicAuthenticationFi
* If multi-tenant and basic auth credentials are invalid, a http error
response is returned.
*/
-@Profile("basicauth")
+@ConditionalOnProperty("fineract.security.basicauth.enabled")
public class TenantAwareBasicAuthenticationFilter extends
BasicAuthenticationFilter {
private static boolean firstRequestProcessed = false;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
index bbc23de..0638c73 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
@@ -38,7 +38,7 @@ import
org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetail
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.filter.GenericFilterBean;
@@ -55,7 +55,7 @@ import org.springframework.web.filter.GenericFilterBean;
* Used to support Oauth2 authentication and the service is loaded only when
"oauth" profile is active.
*/
@Service
-@Profile("oauth")
+@ConditionalOnProperty("fineract.security.oauth.enabled")
public class TenantAwareTenantIdentifierFilter extends GenericFilterBean {
private static boolean firstRequestProcessed = false;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TwoFactorAuthenticationFilter.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TwoFactorAuthenticationFilter.java
index 14dff4b..a5ae91e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TwoFactorAuthenticationFilter.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TwoFactorAuthenticationFilter.java
@@ -34,7 +34,7 @@ import
org.apache.fineract.infrastructure.security.domain.TFAccessToken;
import org.apache.fineract.infrastructure.security.service.TwoFactorService;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
@@ -57,7 +57,7 @@ import org.springframework.web.filter.GenericFilterBean;
* authority regardless of the value of the 'Fineract-Platform-TFA-Token'
header.
*/
@Service
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public class TwoFactorAuthenticationFilter extends GenericFilterBean {
private final TwoFactorService twoFactorService;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorConfigurationServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorConfigurationServiceImpl.java
index 31babfc..a01eaf8 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorConfigurationServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorConfigurationServiceImpl.java
@@ -36,13 +36,13 @@ import
org.apache.fineract.infrastructure.security.domain.TwoFactorConfiguration
import
org.apache.fineract.infrastructure.security.domain.TwoFactorConfigurationRepository;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
-import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
@Service
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public class TwoFactorConfigurationServiceImpl implements
TwoFactorConfigurationService {
private static final String DEFAULT_EMAIL_SUBJECT = "Fineract Two-Factor
Authentication Token";
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorServiceImpl.java
index 8132d68..0134950 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorServiceImpl.java
@@ -39,14 +39,14 @@ import
org.apache.fineract.infrastructure.sms.domain.SmsMessageRepository;
import
org.apache.fineract.infrastructure.sms.scheduler.SmsMessageScheduledJobService;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
-import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
@Service
-@Profile("twofactor")
+@ConditionalOnProperty("fineract.security.2fa.enabled")
public class TwoFactorServiceImpl implements TwoFactorService {
private final AccessTokenGenerationService accessTokenGenerationService;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorUtils.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorUtils.java
deleted file mode 100644
index ee435db..0000000
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/TwoFactorUtils.java
+++ /dev/null
@@ -1,45 +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.security.service;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
-import org.springframework.stereotype.Component;
-
-@Component
-public class TwoFactorUtils {
-
- private static final String TWO_FACTOR_PROFILE_NAME = "twofactor";
-
- private final Environment environment;
-
- @Autowired
- public TwoFactorUtils(Environment environment) {
- this.environment = environment;
- }
-
- public boolean isTwoFactorAuthEnabled() {
- for (final String profile : this.environment.getActiveProfiles()) {
- if (TWO_FACTOR_PROFILE_NAME.equals(profile)) {
- return true;
- }
- }
- return false;
- }
-}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
index 371d72c..cbdd50c 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
@@ -31,13 +31,13 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import
org.apache.fineract.infrastructure.security.api.AuthenticationApiResource;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("singleton")
-@Profile("basicauth")
+@ConditionalOnProperty("fineract.security.basicauth.enabled")
@Path("/self/authentication")
@Tag(name = "Self Authentication", description = "Authenticates the
credentials provided and returns the set roles and permissions allowed")
public class SelfAuthenticationApiResource {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfUserDetailsApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfUserDetailsApiResource.java
index 2104cdb..bbacd50 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfUserDetailsApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfUserDetailsApiResource.java
@@ -30,13 +30,13 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.fineract.infrastructure.security.api.UserDetailsApiResource;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/self/userdetails")
@Component
-@Profile("oauth")
+@ConditionalOnProperty("fineract.security.oauth.enabled")
@Scope("singleton")
@Tag(name = "Self User Details", description = "")
diff --git
a/fineract-provider/properties/oauth/twofactor/application.properties
b/fineract-provider/src/main/resources/application.properties
similarity index 78%
rename from fineract-provider/properties/oauth/twofactor/application.properties
rename to fineract-provider/src/main/resources/application.properties
index 3a2e01d..b4e3949 100644
--- a/fineract-provider/properties/oauth/twofactor/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -17,8 +17,10 @@
# under the License.
#
-spring.profiles.default=basicauth
-spring.profiles.active=oauth,twofactor
+fineract.security.basicauth.enabled=${FINERACT_SECURITY_BASICAUTH_ENABLED:true}
+fineract.security.oauth.enabled=${FINERACT_SECURITY_OAUTH_ENABLED:false}
+fineract.security.2fa.enabled=${FINERACT_SECURITY_2FA_ENABLED:false}
+
management.health.jms.enabled=false
# FINERACT 1296
@@ -34,4 +36,4 @@ management.endpoints.web.exposure.include=health,info
server.forward-headers-strategy=framework
# OAuth authorisation server endpoint
-spring.security.oauth2.resourceserver.jwt.issuer-uri:
http://localhost:9000/auth/realms/fineract
+spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:9000/auth/realms/fineract
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerProviderTest.java
b/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerProviderTest.java
index 30baef9..2f776bc 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerProviderTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerProviderTest.java
@@ -29,14 +29,14 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
@ExtendWith(SpringExtension.class)
+@TestPropertySource("classpath:application-test.properties")
@WebAppConfiguration
-@ActiveProfiles("basicauth")
@ContextConfiguration(classes =
TestsWithoutDatabaseAndNoJobsConfiguration.class)
public class CommandHandlerProviderTest {
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/SpringConfigurationTest.java
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/SpringConfigurationTest.java
index a6d23e4..7a2627f 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/SpringConfigurationTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/SpringConfigurationTest.java
@@ -20,8 +20,8 @@ package
org.apache.fineract.infrastructure.configuration.spring;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
@@ -34,8 +34,8 @@ import
org.springframework.test.context.web.WebAppConfiguration;
* sufficient (as long as the TestsWithoutDatabaseAndNoJobsConfiguration used
extends AbstractApplicationConfiguration).
*/
@ExtendWith(SpringExtension.class)
+@TestPropertySource("classpath:application-test.properties")
@WebAppConfiguration
-@ActiveProfiles("basicauth")
@ContextConfiguration(classes =
TestsWithoutDatabaseAndNoJobsConfiguration.class)
public class SpringConfigurationTest {
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java
index 4ce3cb8..1f51900 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java
@@ -24,6 +24,9 @@ import
org.apache.fineract.infrastructure.core.service.TenantDatabaseUpgradeServ
import org.apache.fineract.infrastructure.jobs.service.JobRegisterService;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
/**
* Spring @Configuration which does not require a running database. It also
does not load any job configuration (as they
@@ -65,4 +68,10 @@ public class TestsWithoutDatabaseAndNoJobsConfiguration
extends AbstractApplicat
DataSource mockDataSource = Mockito.mock(DataSource.class,
Mockito.RETURNS_MOCKS);
return mockDataSource;
}
+
+ @Bean
+ @Primary
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
}
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/boot/tests/AbstractSpringBootWithMariaDB4jIntegrationTest.java
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/boot/tests/AbstractSpringBootWithMariaDB4jIntegrationTest.java
index 39288cf..4ee62bc 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/boot/tests/AbstractSpringBootWithMariaDB4jIntegrationTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/boot/tests/AbstractSpringBootWithMariaDB4jIntegrationTest.java
@@ -21,14 +21,14 @@ package org.apache.fineract.infrastructure.core.boot.tests;
import org.apache.fineract.ServerWithMariaDB4jApplication;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = ServerWithMariaDB4jApplication.Configuration.class)
+@TestPropertySource("classpath:application-test.properties")
@WebAppConfiguration
-@ActiveProfiles("basicauth")
public abstract class AbstractSpringBootWithMariaDB4jIntegrationTest {
// do NOT put any helper methods here!
diff --git
a/fineract-provider/properties/basicauth/twofactor/application.properties
b/fineract-provider/src/test/resources/application-test.properties
similarity index 90%
rename from
fineract-provider/properties/basicauth/twofactor/application.properties
rename to fineract-provider/src/test/resources/application-test.properties
index 03788ec..30b680b 100644
--- a/fineract-provider/properties/basicauth/twofactor/application.properties
+++ b/fineract-provider/src/test/resources/application-test.properties
@@ -17,8 +17,10 @@
# under the License.
#
-spring.profiles.default=basicauth
-spring.profiles.active=basicauth,twofactor
+fineract.security.basicauth.enabled=true
+fineract.security.oauth.enabled=false
+fineract.security.2fa.enabled=false
+
management.health.jms.enabled=false
# FINERACT 1296
diff --git a/oauth2-tests/build.gradle b/oauth2-tests/build.gradle
index f704877..fd20ac4 100644
--- a/oauth2-tests/build.gradle
+++ b/oauth2-tests/build.gradle
@@ -45,7 +45,7 @@ cargo {
}
startStopTimeout = 240000
containerProperties {
- property 'cargo.start.jvmargs', '-Dspring.profiles.active=oauth'
+ property 'cargo.start.jvmargs',
'-Dfineract.security.basicauth.enabled=false
-Dfineract.security.oauth.enabled=true -Dfineract.security.2fa.enabled=false'
property 'cargo.tomcat.connector.keystoreFile',
file("$rootDir/fineract-provider/src/main/resources/keystore.jks")
property 'cargo.tomcat.connector.keystorePass', 'openmf'
property 'cargo.tomcat.httpSecure', true
diff --git a/twofactor-tests/build.gradle b/twofactor-tests/build.gradle
index aa91bb0..e5c45c2 100644
--- a/twofactor-tests/build.gradle
+++ b/twofactor-tests/build.gradle
@@ -45,7 +45,7 @@ cargo {
}
startStopTimeout = 240000
containerProperties {
- property 'cargo.start.jvmargs',
'-Dspring.profiles.active=twofactor,basicauth'
+ property 'cargo.start.jvmargs',
'-Dfineract.security.basicauth.enabled=true
-Dfineract.security.oauth.enabled=false -Dfineract.security.2fa.enabled=true'
property 'cargo.tomcat.connector.keystoreFile',
file("$rootDir/fineract-provider/src/main/resources/keystore.jks")
property 'cargo.tomcat.connector.keystorePass', 'openmf'
property 'cargo.tomcat.httpSecure', true
diff --git
a/twofactor-tests/src/test/java/org/apache/fineract/twofactortests/TwoFactorAuthenticationTest.java
b/twofactor-tests/src/test/java/org/apache/fineract/twofactortests/TwoFactorAuthenticationTest.java
index e3703b4..8269298 100644
---
a/twofactor-tests/src/test/java/org/apache/fineract/twofactortests/TwoFactorAuthenticationTest.java
+++
b/twofactor-tests/src/test/java/org/apache/fineract/twofactortests/TwoFactorAuthenticationTest.java
@@ -111,7 +111,7 @@ public class TwoFactorAuthenticationTest {
.log().ifError().when().post("/fineract-provider/api/v1/authentication?" +
TENANT_IDENTIFIER).asString();
assertFalse(StringUtils.isBlank(json));
Boolean key =
JsonPath.with(json).get("isTwoFactorAuthenticationRequired");
- assertEquals(key, true);
+ assertEquals(true, key);
}
@Test