From fb52484ccc3933a9f6f034196060b1eac893daad Mon Sep 17 00:00:00 2001 From: Gabriel Roldan Date: Tue, 22 Feb 2022 13:31:30 -0300 Subject: [PATCH] Prototype applying georchestra access rules Note the patterns changed from Pattern to String to use Ant patterns instead of Java regex. Rule uri's should be updated accordingly. --- .../gateway/config/RoleBasedAccessRule.java | 5 +-- .../GatewaySecurityAutoconfiguration.java | 40 ++++++++++++++++--- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/georchestra/gateway/config/RoleBasedAccessRule.java b/src/main/java/org/georchestra/gateway/config/RoleBasedAccessRule.java index ff4e6853..ce2512fe 100644 --- a/src/main/java/org/georchestra/gateway/config/RoleBasedAccessRule.java +++ b/src/main/java/org/georchestra/gateway/config/RoleBasedAccessRule.java @@ -19,14 +19,13 @@ package org.georchestra.gateway.config; import java.util.List; -import java.util.regex.Pattern; import lombok.Data; @Data public class RoleBasedAccessRule { - private List interceptUrl; + private List interceptUrl; private boolean anonymous; - private List allowedRoles; + private List allowedRoles = List.of(); } diff --git a/src/main/java/org/georchestra/gateway/security/GatewaySecurityAutoconfiguration.java b/src/main/java/org/georchestra/gateway/security/GatewaySecurityAutoconfiguration.java index a8933ef9..371e2752 100644 --- a/src/main/java/org/georchestra/gateway/security/GatewaySecurityAutoconfiguration.java +++ b/src/main/java/org/georchestra/gateway/security/GatewaySecurityAutoconfiguration.java @@ -18,6 +18,10 @@ */ package org.georchestra.gateway.security; +import java.util.List; + +import org.georchestra.gateway.config.GatewayConfigProperties; +import org.georchestra.gateway.config.RoleBasedAccessRule; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -27,6 +31,8 @@ import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity.AuthorizeExchangeSpec; +import org.springframework.security.config.web.server.ServerHttpSecurity.AuthorizeExchangeSpec.Access; import org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2LoginSpec; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient; @@ -41,12 +47,13 @@ @Configuration(proxyBeanMethods = false) @EnableWebFluxSecurity @EnableConfigurationProperties(OAuth2ProxyConfigProperties.class) -@Slf4j +@Slf4j(topic = "org.georchestra.gateway.security") public class GatewaySecurityAutoconfiguration { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, - @Value("${georchestra.gateway.security.ldap.enabled:false}") boolean ldapEnabled) throws Exception { + @Value("${georchestra.gateway.security.ldap.enabled:false}") boolean ldapEnabled, + GatewayConfigProperties config) throws Exception { // disable csrf and cors or the websocket connection gets a 403 Forbidden. // Revisit. @@ -59,10 +66,12 @@ public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, http.httpBasic().and().formLogin(); } // configure path matchers - http.authorizeExchange()// - .pathMatchers("/", "/header/**").permitAll()// - .pathMatchers("/ws/**").permitAll()// - .pathMatchers("/**").authenticated(); + applyAccessRules(http, config); + +// http.authorizeExchange()// +// .pathMatchers("/", "/header/**").permitAll()// +// .pathMatchers("/ws/**").permitAll()// +// .pathMatchers("/**").authenticated(); return http.build(); } @@ -129,4 +138,23 @@ public WebClient oauth2WebClient(OAuth2ProxyConfigProperties proxyConfig) { return webClient; } + private ServerHttpSecurity applyAccessRules(ServerHttpSecurity http, GatewayConfigProperties config) { + AuthorizeExchangeSpec authorizeExchange = http.authorizeExchange(); + + for (RoleBasedAccessRule rule : config.getGlobalAccessRules()) { + List antPatterns = rule.getInterceptUrl(); + boolean anonymous = rule.isAnonymous(); + List allowedRoles = rule.getAllowedRoles(); + Access access = authorizeExchange.pathMatchers(antPatterns.toArray(String[]::new)); + if (anonymous) { + log.info("Access rule: {} anonymous"); + access.permitAll(); + } else { + log.info("Access rule: {} has any role: {}", antPatterns, allowedRoles); + access.hasAnyAuthority(allowedRoles.toArray(String[]::new)); + } + } + + return http; + } }