Skip to content

Commit

Permalink
Merge pull request #3 from georchestra/oauth2-client-proxy-settings
Browse files Browse the repository at this point in the history
trying to implement proxy configuration for the oauth2 client
  • Loading branch information
groldan committed Mar 28, 2022
2 parents 50f01c2 + d5049af commit ab932b1
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 63 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ LDAP Authentication is enabled and set up through the following
configuration properties in `application.yml`:

```yaml
ldap:
georchestra.security.ldap:
enabled: true
url: ${ldapScheme}://${ldapHost}:${ldapPort}
baseDn: ${ldapBaseDn:dc=georchestra,dc=org}
Expand All @@ -27,7 +27,7 @@ ldap:
rolesSearchFilter: ${ldapRolesSearchFilter:(member={0})}
```

If `ldap.enabled` is `false`,the log-in page won't show the username/password form inputs.
If `georchestra.security.ldap.enabled` is `false`,the log-in page won't show the username/password form inputs.

## Data directory property sources

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<version>2.6.3</version>
<relativePath></relativePath>
<!-- lookup parent from repository -->
</parent>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* Copyright (C) 2022 by the geOrchestra PSC
*
* This file is part of geOrchestra.
*
* geOrchestra is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* geOrchestra. If not, see <http://www.gnu.org/licenses/>.
*/
package org.georchestra.gateway.filter.headers;

import java.net.URI;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,36 @@
*/
package org.georchestra.gateway.security;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
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.OAuth2LoginSpec;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.WebClientReactiveAuthorizationCodeTokenResponseClient;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
import lombok.extern.slf4j.Slf4j;
import reactor.netty.http.client.HttpClient;
import reactor.netty.transport.ProxyProvider;

@Configuration(proxyBeanMethods = false)
@EnableWebFluxSecurity
@EnableConfigurationProperties(OAuth2ProxyConfigProperties.class)
@Slf4j
public class GatewaySecurityAutoconfiguration {

private @Value("${ldap.enabled:false}") boolean ldapEnabled;

@Bean
SecurityWebFilterChain configure(ServerHttpSecurity http) throws Exception {
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http,
@Value("${georchestra.gateway.security.ldap.enabled:false}") boolean ldapEnabled) throws Exception {

// disable csrf and cors or the websocket connection gets a 403 Forbidden.
// Revisit.
http.csrf().disable().cors().disable();
Expand All @@ -51,4 +66,67 @@ SecurityWebFilterChain configure(ServerHttpSecurity http) throws Exception {

return http.build();
}

/**
* Configures the OAuth2 client to use the HTTP proxy if enabled, by means of
* {@linkplain #oauth2WebClient}
* <p>
* {@link OAuth2LoginSpec ServerHttpSecurity$OAuth2LoginSpec#createDefault()}
* will return a {@link ReactiveAuthenticationManager} by first looking up a
* {@link ReactiveOAuth2AccessTokenResponseClient
* ReactiveOAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest>}
* in the application context, and creating a default one if none is found.
* <p>
* We provide such bean here to have it configured with an {@link WebClient HTTP
* client} that will use the {@link OAuth2ProxyConfigProperties configured} HTTP
* proxy.
*/
@Bean
public ReactiveOAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> reactiveOAuth2AccessTokenResponseClient(
@Qualifier("oauth2WebClient") WebClient oauth2WebClient) {

WebClientReactiveAuthorizationCodeTokenResponseClient client = new WebClientReactiveAuthorizationCodeTokenResponseClient();
client.setWebClient(oauth2WebClient);
return client;
}

/**
* {@link WebClient} to use when performing HTTP POST requests to the OAuth2
* service providers, that can be configured to use an HTTP proxy through the
* {@link OAuth2ProxyConfigProperties} configuration properties.
*
* @param proxyConfig defines the HTTP proxy settings specific for the OAuth2
* client. If not
* {@link OAuth2ProxyConfigProperties#isEnabled() enabled},
* the {@code WebClient} will use the proxy configured
* through System properties ({@literal http(s).proxyHost}
* and {@literal http(s).proxyPort}), if any.
*/
@Bean("oauth2WebClient")
public WebClient oauth2WebClient(OAuth2ProxyConfigProperties proxyConfig) {
final String proxyHost = proxyConfig.getHost();
final Integer proxyPort = proxyConfig.getPort();
final String proxyUser = proxyConfig.getUsername();
final String proxyPassword = proxyConfig.getPassword();

HttpClient httpClient = HttpClient.create();
if (proxyConfig.isEnabled()) {
if (proxyHost == null || proxyPort == null) {
throw new IllegalStateException("OAuth2 client HTTP proxy is enabled, but host and port not provided");
}
log.info("Oauth2 client will use HTTP proxy {}:{}", proxyHost, proxyPort);
httpClient = httpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP).host(proxyHost).port(proxyPort)
.username(proxyUser).password(user -> {
return proxyPassword;
}));
} else {
log.info("Oauth2 client will use HTTP proxy from System properties if provided");
httpClient = httpClient.proxyWithSystemProperties();
}
ReactorClientHttpConnector conn = new ReactorClientHttpConnector(httpClient);

WebClient webClient = WebClient.builder().clientConnector(conn).build();
return webClient;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2022 by the geOrchestra PSC
*
* This file is part of geOrchestra.
*
* geOrchestra is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* geOrchestra. If not, see <http://www.gnu.org/licenses/>.
*/
package org.georchestra.gateway.security;

import org.springframework.boot.context.properties.ConfigurationProperties;

import lombok.Data;

@ConfigurationProperties(prefix = "georchestra.gateway.security.oauth2.proxy")
public @Data class OAuth2ProxyConfigProperties {
private boolean enabled;
private String host;
private Integer port;
private String username;
private String password;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* Copyright (C) 2022 by the geOrchestra PSC
*
* This file is part of geOrchestra.
*
* geOrchestra is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* geOrchestra. If not, see <http://www.gnu.org/licenses/>.
*/
package org.georchestra.gateway.security.ldap;

import lombok.Data;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* Copyright (C) 2022 by the geOrchestra PSC
*
* This file is part of geOrchestra.
*
* geOrchestra is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* geOrchestra. If not, see <http://www.gnu.org/licenses/>.
*/
package org.georchestra.gateway.security.ldap;

import java.util.Arrays;
Expand All @@ -23,12 +41,12 @@
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;

@Configuration(proxyBeanMethods = true)
@ConditionalOnProperty(name = "ldap.enabled", havingValue = "true", matchIfMissing = false)
@ConditionalOnProperty(prefix = "georchestra.gateway.security.ldap", name = "enabled", havingValue = "true", matchIfMissing = false)
@EnableConfigurationProperties
public class LdapSecurityAutoConfiguration {

@Bean
@ConfigurationProperties(prefix = "ldap")
@ConfigurationProperties(prefix = "georchestra.gateway.security.ldap")
LdapConfigProperties ldapConfigProperties() {
return new LdapConfigProperties();
}
Expand Down
Loading

0 comments on commit ab932b1

Please sign in to comment.