FINERACT-1971 Fixing CORS config
This commit is contained in:
committed by
Arnold Gálovics
parent
1a29266d86
commit
8aa56aad58
-49
@@ -1,49 +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.filters;
|
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter that returns a response with headers that allows for Cross-Origin Requests (CORs) to be performed against the
|
|
||||||
* platform API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ResponseCorsFilter extends OncePerRequestFilter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
|
||||||
throws ServletException, IOException {
|
|
||||||
response.addHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
||||||
|
|
||||||
final String reqHead = request.getHeader("Access-Control-Request-Headers");
|
|
||||||
|
|
||||||
if (StringUtils.hasText(reqHead)) {
|
|
||||||
response.addHeader("Access-Control-Allow-Headers", reqHead);
|
|
||||||
}
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+22
-10
@@ -24,6 +24,7 @@ import static org.springframework.security.authorization.AuthorityAuthorizationM
|
|||||||
import static org.springframework.security.authorization.AuthorizationManagers.allOf;
|
import static org.springframework.security.authorization.AuthorizationManagers.allOf;
|
||||||
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
|
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.apache.fineract.commands.domain.CommandSourceRepository;
|
import org.apache.fineract.commands.domain.CommandSourceRepository;
|
||||||
import org.apache.fineract.commands.service.CommandSourceService;
|
import org.apache.fineract.commands.service.CommandSourceService;
|
||||||
@@ -35,7 +36,6 @@ import org.apache.fineract.infrastructure.core.filters.CorrelationHeaderFilter;
|
|||||||
import org.apache.fineract.infrastructure.core.filters.IdempotencyStoreFilter;
|
import org.apache.fineract.infrastructure.core.filters.IdempotencyStoreFilter;
|
||||||
import org.apache.fineract.infrastructure.core.filters.IdempotencyStoreHelper;
|
import org.apache.fineract.infrastructure.core.filters.IdempotencyStoreHelper;
|
||||||
import org.apache.fineract.infrastructure.core.filters.RequestResponseFilter;
|
import org.apache.fineract.infrastructure.core.filters.RequestResponseFilter;
|
||||||
import org.apache.fineract.infrastructure.core.filters.ResponseCorsFilter;
|
|
||||||
import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
|
import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
|
||||||
import org.apache.fineract.infrastructure.core.service.MDCWrapper;
|
import org.apache.fineract.infrastructure.core.service.MDCWrapper;
|
||||||
import org.apache.fineract.infrastructure.instancemode.filter.FineractInstanceModeApiFilter;
|
import org.apache.fineract.infrastructure.instancemode.filter.FineractInstanceModeApiFilter;
|
||||||
@@ -60,6 +60,7 @@ import org.springframework.http.HttpMethod;
|
|||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.ProviderManager;
|
import org.springframework.security.authentication.ProviderManager;
|
||||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
@@ -69,6 +70,9 @@ import org.springframework.security.web.SecurityFilterChain;
|
|||||||
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.context.SecurityContextHolderFilter;
|
import org.springframework.security.web.context.SecurityContextHolderFilter;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnProperty("fineract.security.basicauth.enabled")
|
@ConditionalOnProperty("fineract.security.basicauth.enabled")
|
||||||
@@ -131,13 +135,13 @@ public class SecurityConfig {
|
|||||||
.requestMatchers(antMatcher("/api/**"))
|
.requestMatchers(antMatcher("/api/**"))
|
||||||
.access(allOf(fullyAuthenticated(), hasAuthority("TWOFACTOR_AUTHENTICATED"))); //
|
.access(allOf(fullyAuthenticated(), hasAuthority("TWOFACTOR_AUTHENTICATED"))); //
|
||||||
}).httpBasic((httpBasic) -> httpBasic.authenticationEntryPoint(basicAuthenticationEntryPoint())) //
|
}).httpBasic((httpBasic) -> httpBasic.authenticationEntryPoint(basicAuthenticationEntryPoint())) //
|
||||||
.csrf((csrf) -> csrf.disable()) // NOSONAR only creating a service that is used by non-browser clients
|
.cors(Customizer.withDefaults()).csrf((csrf) -> csrf.disable()) // NOSONAR only creating a service that
|
||||||
|
// is used by non-browser clients
|
||||||
.sessionManagement((smc) -> smc.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) //
|
.sessionManagement((smc) -> smc.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) //
|
||||||
.addFilterBefore(tenantAwareBasicAuthenticationFilter(), SecurityContextHolderFilter.class) //
|
.addFilterBefore(tenantAwareBasicAuthenticationFilter(), SecurityContextHolderFilter.class) //
|
||||||
.addFilterAfter(requestResponseFilter(), ExceptionTranslationFilter.class) //
|
.addFilterAfter(requestResponseFilter(), ExceptionTranslationFilter.class) //
|
||||||
.addFilterAfter(correlationHeaderFilter(), RequestResponseFilter.class) //
|
.addFilterAfter(correlationHeaderFilter(), RequestResponseFilter.class) //
|
||||||
.addFilterAfter(responseCorsFilter(), CorrelationHeaderFilter.class) //
|
.addFilterAfter(fineractInstanceModeApiFilter(), CorrelationHeaderFilter.class); //
|
||||||
.addFilterAfter(fineractInstanceModeApiFilter(), ResponseCorsFilter.class); //
|
|
||||||
if (!Objects.isNull(loanCOBFilterHelper)) {
|
if (!Objects.isNull(loanCOBFilterHelper)) {
|
||||||
http.addFilterAfter(loanCOBApiFilter(), FineractInstanceModeApiFilter.class) //
|
http.addFilterAfter(loanCOBApiFilter(), FineractInstanceModeApiFilter.class) //
|
||||||
.addFilterAfter(idempotencyStoreFilter(), LoanCOBApiFilter.class); //
|
.addFilterAfter(idempotencyStoreFilter(), LoanCOBApiFilter.class); //
|
||||||
@@ -146,9 +150,9 @@ public class SecurityConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fineractProperties.getSecurity().getTwoFactor().isEnabled()) {
|
if (fineractProperties.getSecurity().getTwoFactor().isEnabled()) {
|
||||||
http.addFilterAfter(twoFactorAuthenticationFilter(), ResponseCorsFilter.class);
|
http.addFilterAfter(twoFactorAuthenticationFilter(), CorrelationHeaderFilter.class);
|
||||||
} else {
|
} else {
|
||||||
http.addFilterAfter(insecureTwoFactorAuthenticationFilter(), ResponseCorsFilter.class);
|
http.addFilterAfter(insecureTwoFactorAuthenticationFilter(), CorrelationHeaderFilter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverProperties.getSsl().isEnabled()) {
|
if (serverProperties.getSsl().isEnabled()) {
|
||||||
@@ -186,10 +190,6 @@ public class SecurityConfig {
|
|||||||
return new CorrelationHeaderFilter(fineractProperties, mdcWrapper);
|
return new CorrelationHeaderFilter(fineractProperties, mdcWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseCorsFilter responseCorsFilter() {
|
|
||||||
return new ResponseCorsFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TenantAwareBasicAuthenticationFilter tenantAwareBasicAuthenticationFilter() throws Exception {
|
public TenantAwareBasicAuthenticationFilter tenantAwareBasicAuthenticationFilter() throws Exception {
|
||||||
TenantAwareBasicAuthenticationFilter filter = new TenantAwareBasicAuthenticationFilter(authenticationManagerBean(),
|
TenantAwareBasicAuthenticationFilter filter = new TenantAwareBasicAuthenticationFilter(authenticationManagerBean(),
|
||||||
basicAuthenticationEntryPoint(), toApiJsonSerializer, configurationDomainService, cacheWritePlatformService,
|
basicAuthenticationEntryPoint(), toApiJsonSerializer, configurationDomainService, cacheWritePlatformService,
|
||||||
@@ -224,4 +224,16 @@ public class SecurityConfig {
|
|||||||
providerManager.setEraseCredentialsAfterAuthentication(false);
|
providerManager.setEraseCredentialsAfterAuthentication(false);
|
||||||
return providerManager;
|
return providerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsConfigurationSource corsConfigurationSource() {
|
||||||
|
CorsConfiguration configuration = new CorsConfiguration();
|
||||||
|
configuration.setAllowedOriginPatterns(List.of("*"));
|
||||||
|
configuration.setAllowedMethods(List.of("*"));
|
||||||
|
configuration.setAllowCredentials(true);
|
||||||
|
configuration.setAllowedHeaders(List.of("*"));
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", configuration);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user