FINERACT-2326: Add configuration options for CORS handling
This commit is contained in:
+13
@@ -519,6 +519,7 @@ public class FineractProperties {
|
||||
private FineractSecurityTwoFactorAuth twoFactor;
|
||||
private FineractSecurityHsts hsts;
|
||||
private FineractSecurityOAuth2Properties oauth2;
|
||||
private CorsProperties cors;
|
||||
|
||||
public void set2fa(FineractSecurityTwoFactorAuth twoFactor) {
|
||||
this.twoFactor = twoFactor;
|
||||
@@ -688,4 +689,16 @@ public class FineractProperties {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class CorsProperties {
|
||||
|
||||
private boolean enabled;
|
||||
private List<String> allowedOrigins;
|
||||
private List<String> allowedMethods;
|
||||
private List<String> allowedHeaders;
|
||||
private List<String> exposedHeaders;
|
||||
private boolean allowCredentials;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-8
@@ -160,8 +160,8 @@ public class SecurityConfig {
|
||||
.requestMatchers(antMatcher("/api/**"))
|
||||
.access(allOf(authorizationManagers.toArray(new AuthorizationManager[0]))); //
|
||||
}).httpBasic((httpBasic) -> httpBasic.authenticationEntryPoint(basicAuthenticationEntryPoint())) //
|
||||
.cors(Customizer.withDefaults()).csrf(AbstractHttpConfigurer::disable) // NOSONAR only creating a
|
||||
// service that
|
||||
.csrf(AbstractHttpConfigurer::disable) // NOSONAR only creating a
|
||||
// service that
|
||||
// is used by non-browser clients
|
||||
.sessionManagement((smc) -> smc.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) //
|
||||
.addFilterBefore(tenantAwareBasicAuthenticationFilter(), SecurityContextHolderFilter.class) //
|
||||
@@ -189,6 +189,9 @@ public class SecurityConfig {
|
||||
http.requiresChannel(channel -> channel.anyRequest().requiresSecure()).headers(
|
||||
headers -> headers.httpStrictTransportSecurity(hsts -> hsts.includeSubDomains(true).maxAgeInSeconds(31536000)));
|
||||
}
|
||||
if (fineractProperties.getSecurity().getCors().isEnabled()) {
|
||||
http.cors(Customizer.withDefaults());
|
||||
}
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@@ -258,13 +261,16 @@ public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
configuration.setAllowedOriginPatterns(List.of("*"));
|
||||
configuration.setAllowedMethods(List.of("*"));
|
||||
configuration.setAllowCredentials(true);
|
||||
configuration.setAllowedHeaders(List.of("*"));
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
FineractProperties.CorsProperties corsConfiguration = fineractProperties.getSecurity().getCors();
|
||||
config.setAllowedOrigins(corsConfiguration.getAllowedOrigins());
|
||||
config.setAllowedMethods(corsConfiguration.getAllowedMethods());
|
||||
config.setAllowedHeaders(corsConfiguration.getAllowedHeaders());
|
||||
config.setExposedHeaders(corsConfiguration.getExposedHeaders());
|
||||
config.setAllowCredentials(corsConfiguration.isAllowCredentials()); // if you use cookies / Authorization header
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-1
@@ -55,6 +55,7 @@ import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
@@ -78,6 +79,9 @@ import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
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;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
@Configuration
|
||||
@@ -121,6 +125,10 @@ public class AuthorizationServerConfig {
|
||||
http.securityMatcher("/swagger-ui/**", "/fineract.json", "/actuator/**", "/legacy-docs/apiLive.htm")
|
||||
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()).csrf(AbstractHttpConfigurer::disable);
|
||||
|
||||
if (fineractProperties.getSecurity().getCors().isEnabled()) {
|
||||
http.cors(Customizer.withDefaults());
|
||||
}
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@@ -137,6 +145,10 @@ public class AuthorizationServerConfig {
|
||||
.exceptionHandling(exceptions -> exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")))
|
||||
.apply(authorizationServerConfigurer);
|
||||
|
||||
if (fineractProperties.getSecurity().getCors().isEnabled()) {
|
||||
http.cors(Customizer.withDefaults());
|
||||
}
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@@ -144,7 +156,6 @@ public class AuthorizationServerConfig {
|
||||
@Order(3)
|
||||
public SecurityFilterChain protectedEndpoints(HttpSecurity http) throws Exception {
|
||||
http
|
||||
// .securityMatcher(new AntPathRequestMatcher("/api/**"))
|
||||
// TODO: Make it configurable
|
||||
.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> {
|
||||
auth.anyRequest().authenticated();
|
||||
@@ -171,9 +182,27 @@ public class AuthorizationServerConfig {
|
||||
if (fineractProperties.getSecurity().getTwoFactor().isEnabled()) {
|
||||
http.addFilterAfter(twoFactorAuthenticationFilter(), CorrelationHeaderFilter.class);
|
||||
}
|
||||
if (fineractProperties.getSecurity().getCors().isEnabled()) {
|
||||
http.cors(Customizer.withDefaults());
|
||||
}
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
FineractProperties.CorsProperties corsConfiguration = fineractProperties.getSecurity().getCors();
|
||||
config.setAllowedOrigins(corsConfiguration.getAllowedOrigins());
|
||||
config.setAllowedMethods(corsConfiguration.getAllowedMethods());
|
||||
config.setAllowedHeaders(corsConfiguration.getAllowedHeaders());
|
||||
config.setExposedHeaders(corsConfiguration.getExposedHeaders());
|
||||
config.setAllowCredentials(corsConfiguration.isAllowCredentials()); // if you use cookies / Authorization header
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
return source;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OncePerRequestFilter tenantAwareAuthenticationFilter() {
|
||||
return new TenantAwareAuthenticationFilter(resolver(), tenantDetailsService);
|
||||
|
||||
@@ -26,6 +26,14 @@ fineract.security.oauth2.enabled=${FINERACT_SECURITY_OAUTH_ENABLED:false}
|
||||
fineract.security.2fa.enabled=${FINERACT_SECURITY_2FA_ENABLED:false}
|
||||
fineract.security.hsts.enabled=${FINERACT_SECURITY_HSTS_ENABLED:false}
|
||||
|
||||
#CORS configuration
|
||||
fineract.security.cors.enabled=${FINERACT_SECURITY_CORS_ENABLED:true}
|
||||
fineract.security.cors.allowed-origins=${FINERACT_SECURITY_CORS_ALLOWED_ORIGINS:"*"}
|
||||
fineract.security.cors.allowed-methods=${FINERACT_SECURITY_CORS_ALLOWED_METHODS:"*"}
|
||||
fineract.security.cors.allowed-headers=${FINERACT_SECURITY_CORS_ALLOWED_HEADERS:"*"}
|
||||
fineract.security.cors.exposed-headers=${FINERACT_SECURITY_CORS_EXPOSED_HEADERS:"*"}
|
||||
fineract.security.cors.allow-credentials=${FINERACT_SECURITY_CORS_ALLOW_CREDENTIALS:true}
|
||||
|
||||
# EXAMPLE: OAuth2 client configuration (frontend-client)
|
||||
fineract.security.oauth2.client.registrations.frontend-client.client-id=${FINERACT_SECURITY_OAUTH2_CLIENTS_FRONTEND_ID:frontend-client}
|
||||
fineract.security.oauth2.client.registrations.frontend-client.scopes=${FINERACT_SECURITY_OAUTH2_CLIENTS_FRONTEND_SCOPES:read,write}
|
||||
|
||||
@@ -25,6 +25,14 @@ fineract.security.oauth2.enabled=false
|
||||
fineract.security.2fa.enabled=false
|
||||
fineract.security.hsts.enabled=false
|
||||
|
||||
#CORS configuration
|
||||
fineract.security.cors.enabled=true
|
||||
fineract.security.cors.allowed-origins="*"
|
||||
fineract.security.cors.allowed-methods="*"
|
||||
fineract.security.cors.allowed-headers="*"
|
||||
fineract.security.cors.exposed-headers="*"
|
||||
fineract.security.cors.allow-credentials=true
|
||||
|
||||
fineract.tenant.host=localhost
|
||||
fineract.tenant.port=3306
|
||||
fineract.tenant.username=root
|
||||
|
||||
Reference in New Issue
Block a user