Skip to content

Commit

Permalink
Add JDBC and LDAP security plugins
Browse files Browse the repository at this point in the history
Both plugins are enabled by default, can be disabled with

```
geoserver.security.ldap=false
geoserver.security.jdbc=false
```
  • Loading branch information
groldan committed Oct 25, 2024
1 parent 4aec64e commit a24873d
Show file tree
Hide file tree
Showing 15 changed files with 455 additions and 2 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ Only a curated list of the [vast amount](http://geoserver.org/release/stable/) o
- cog
- importer
- imagepyramid
- gt-iau-wkt ([https://docs.geotools.org/latest/userguide/library/referencing/iau.html](IAU planetary CRS Plugin)(
- [IAU planetary CRS Plugin](https://docs.geotools.org/latest/userguide/library/referencing/iau.html)
- JDBC Security
- LDAP Security

Advanced ACL system is available through the project [GeoServer ACL](https://github.com/geoserver/geoserver-acl) which offers the same capacities as GeoFence.

Expand Down
8 changes: 8 additions & 0 deletions src/apps/geoserver/webui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-core</artifactId>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-sec-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-sec-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-wms</artifactId>
Expand Down
26 changes: 26 additions & 0 deletions src/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,32 @@
<artifactId>gs-web-sec-core</artifactId>
<version>${gs.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver.security</groupId>
<artifactId>gs-sec-jdbc</artifactId>
<version>${gs.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-sec-jdbc</artifactId>
<version>${gs.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver.security</groupId>
<artifactId>gs-sec-ldap</artifactId>
<version>${gs.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-sec-ldap</artifactId>
<version>${gs.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver</groupId>
<artifactId>gs-rest</artifactId>
Expand Down
18 changes: 18 additions & 0 deletions src/starters/security/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,24 @@
<artifactId>gs-web-sec-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.geoserver.security</groupId>
<artifactId>gs-sec-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-sec-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.geoserver.security</groupId>
<artifactId>gs-sec-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-sec-ldap</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<!-- need it on the classpath just to avoid ClassNotFoundExceptions when loading some GeoServer bean definitions -->
<groupId>javax.servlet</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.jdbc;

import org.geoserver.cloud.autoconfigure.security.ConditionalOnGeoServerSecurityEnabled;
import org.geoserver.cloud.autoconfigure.security.GeoServerSecurityAutoConfiguration;
import org.geoserver.cloud.config.factory.FilteringXmlBeanDefinitionReader;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ImportResource;

/** {@link AutoConfiguration @AutoConfiguration} to enable {@code gs-sec-jdbc} */
// run before GeoServerSecurityAutoConfiguration so the provider is available when
// GeoServerSecurityManager calls GeoServerExtensions.extensions(GeoServerSecurityProvider.class)
@AutoConfiguration(before = GeoServerSecurityAutoConfiguration.class)
@EnableConfigurationProperties(JDBCSecurityConfigProperties.class)
@ConditionalOnGeoServerSecurityEnabled
@ConditionalOnProperty(
name = "geoserver.security.jdbc",
havingValue = "true",
matchIfMissing = true)
@ImportResource(
reader = FilteringXmlBeanDefinitionReader.class, //
locations = "jar:gs-sec-jdbc-.*!/applicationContext.xml")
public class JDBCSecurityAutoConfiguration {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.jdbc;

import lombok.Data;

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

@ConfigurationProperties("geoserver.security")
@Data
public class JDBCSecurityConfigProperties {

/** Enable or disable GeoServer JDBC Security plugin */
private boolean jdbc = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.jdbc;

import org.geoserver.cloud.autoconfigure.security.ConditionalOnGeoServerSecurityEnabled;
import org.geoserver.cloud.autoconfigure.security.GeoServerSecurityAutoConfiguration;
import org.geoserver.cloud.config.factory.FilteringXmlBeanDefinitionReader;
import org.geoserver.security.web.auth.AuthenticationFilterPanelInfo;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ImportResource;

/**
* {@link AutoConfiguration @AutoConfiguration} to enable {@code gs-web-sec-jdbc} when running with
* the webui components in the classpath
*/
// run before GeoServerSecurityAutoConfiguration so the provider is available when
// GeoServerSecurityManager calls GeoServerExtensions.extensions(GeoServerSecurityProvider.class)
@AutoConfiguration(before = GeoServerSecurityAutoConfiguration.class)
@EnableConfigurationProperties(JDBCSecurityConfigProperties.class)
@ConditionalOnClass(AuthenticationFilterPanelInfo.class)
@ConditionalOnGeoServerSecurityEnabled
@ConditionalOnProperty(
name = "geoserver.security.jdbc",
havingValue = "true",
matchIfMissing = true)
@ImportResource(
reader = FilteringXmlBeanDefinitionReader.class, //
locations = "jar:gs-web-sec-jdbc-.*!/applicationContext.xml")
public class JDBCSecurityWebUIAutoConfiguration {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.ldap;

import org.geoserver.cloud.autoconfigure.security.ConditionalOnGeoServerSecurityEnabled;
import org.geoserver.cloud.autoconfigure.security.GeoServerSecurityAutoConfiguration;
import org.geoserver.cloud.config.factory.FilteringXmlBeanDefinitionReader;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ImportResource;

/** {@link AutoConfiguration @AutoConfiguration} to enable {@code gs-sec-ldap} */
// run before GeoServerSecurityAutoConfiguration so the provider is available when
// GeoServerSecurityManager calls GeoServerExtensions.extensions(GeoServerSecurityProvider.class)
@AutoConfiguration(before = GeoServerSecurityAutoConfiguration.class)
@EnableConfigurationProperties(LDAPSecurityConfigProperties.class)
@ConditionalOnGeoServerSecurityEnabled
@ConditionalOnProperty(
name = "geoserver.security.ldap",
havingValue = "true",
matchIfMissing = true)
@ImportResource(
reader = FilteringXmlBeanDefinitionReader.class, //
locations = "jar:gs-sec-ldap-.*!/applicationContext.xml")
public class LDAPSecurityAutoConfiguration {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.ldap;

import lombok.Data;

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

@ConfigurationProperties("geoserver.security")
@Data
public class LDAPSecurityConfigProperties {

/** Enable or disable GeoServer LDAP Security plugin */
private boolean ldap = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.ldap;

import org.geoserver.cloud.autoconfigure.security.ConditionalOnGeoServerSecurityEnabled;
import org.geoserver.cloud.autoconfigure.security.GeoServerSecurityAutoConfiguration;
import org.geoserver.cloud.config.factory.FilteringXmlBeanDefinitionReader;
import org.geoserver.security.web.auth.AuthenticationFilterPanelInfo;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ImportResource;

/**
* {@link AutoConfiguration @AutoConfiguration} to enable {@code gs-web-sec-ldap} when running with
* the webui components in the classpath
*/
// run before GeoServerSecurityAutoConfiguration so the provider is available when
// GeoServerSecurityManager calls GeoServerExtensions.extensions(GeoServerSecurityProvider.class)
@AutoConfiguration(before = GeoServerSecurityAutoConfiguration.class)
@EnableConfigurationProperties(LDAPSecurityConfigProperties.class)
@ConditionalOnClass(AuthenticationFilterPanelInfo.class)
@ConditionalOnGeoServerSecurityEnabled
@ConditionalOnProperty(
name = "geoserver.security.ldap",
havingValue = "true",
matchIfMissing = true)
@ImportResource(
reader = FilteringXmlBeanDefinitionReader.class, //
locations = "jar:gs-web-sec-ldap-.*!/applicationContext.xml")
public class LDAPSecurityWebUIAutoConfiguration {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.geoserver.cloud.autoconfigure.authzn.AuthKeyAutoConfiguration,\
org.geoserver.cloud.autoconfigure.authzn.GatewayPreAuthenticationAutoConfiguration,\
org.geoserver.cloud.autoconfigure.authzn.GatewaySharedAuthenticationAutoConfiguration
org.geoserver.cloud.autoconfigure.authzn.GatewaySharedAuthenticationAutoConfiguration,\
org.geoserver.cloud.autoconfigure.security.jdbc.JDBCSecurityAutoConfiguration,\
org.geoserver.cloud.autoconfigure.security.jdbc.JDBCSecurityWebUIAutoConfiguration,\
org.geoserver.cloud.autoconfigure.security.ldap.LDAPSecurityAutoConfiguration,\
org.geoserver.cloud.autoconfigure.security.ldap.LDAPSecurityWebUIAutoConfiguration
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.jdbc;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.jdbc.JDBCSecurityProvider;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;

class JDBCSecurityAutoConfigurationTest {

private WebApplicationContextRunner runner =
new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(JDBCSecurityAutoConfiguration.class))
.withBean(
GeoServerSecurityManager.class,
() -> mock(GeoServerSecurityManager.class));

@Test
void testExpectedBeans() {
runner.run(
context ->
assertThat(context)
.hasNotFailed()
.hasSingleBean(JDBCSecurityProvider.class)
.getBean(JDBCSecurityConfigProperties.class)
.hasFieldOrPropertyWithValue("jdbc", true));
}

@Test
void testDisabled() {
runner.withPropertyValues("geoserver.security.jdbc=false")
.run(
context ->
assertThat(context)
.hasNotFailed()
.doesNotHaveBean(JDBCSecurityProvider.class)
.doesNotHaveBean(JDBCSecurityConfigProperties.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* (c) 2024 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/
package org.geoserver.cloud.autoconfigure.security.jdbc;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

import org.geoserver.platform.ModuleStatusImpl;
import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.web.auth.AuthenticationFilterPanelInfo;
import org.geoserver.security.web.jdbc.JDBCAuthProviderPanelInfo;
import org.geoserver.security.web.jdbc.JDBCRoleServicePanelInfo;
import org.geoserver.security.web.jdbc.JDBCUserGroupServicePanelInfo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;

class JDBCSecurityWebUIAutoConfigurationTest {

private WebApplicationContextRunner runner =
new WebApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(
JDBCSecurityAutoConfiguration.class,
JDBCSecurityWebUIAutoConfiguration.class))
.withBean(
GeoServerSecurityManager.class,
() -> mock(GeoServerSecurityManager.class));

@Test
void testConditionalOnClassNoMatch() {
runner.withClassLoader(new FilteredClassLoader(AuthenticationFilterPanelInfo.class))
.run(
context ->
assertThat(context)
.hasNotFailed()
.doesNotHaveBean(JDBCUserGroupServicePanelInfo.class)
.doesNotHaveBean(JDBCRoleServicePanelInfo.class)
.doesNotHaveBean(JDBCAuthProviderPanelInfo.class)
.doesNotHaveBean("jdbcSecurityWebExtension"));
}

@Test
void testConditionalOnClassMatch() {
runner.run(
context ->
assertThat(context)
.hasNotFailed()
.hasSingleBean(JDBCUserGroupServicePanelInfo.class)
.hasSingleBean(JDBCRoleServicePanelInfo.class)
.hasSingleBean(JDBCAuthProviderPanelInfo.class)
.hasBean("jdbcSecurityWebExtension")
.getBean("jdbcSecurityWebExtension")
.isInstanceOf(ModuleStatusImpl.class));
}

@Test
void testDisabled() {
runner.withPropertyValues("geoserver.security.jdbc=false")
.run(
context ->
assertThat(context)
.hasNotFailed()
.doesNotHaveBean(JDBCUserGroupServicePanelInfo.class)
.doesNotHaveBean(JDBCRoleServicePanelInfo.class)
.doesNotHaveBean(JDBCAuthProviderPanelInfo.class)
.doesNotHaveBean("jdbcSecurityWebExtension"));
}
}
Loading

0 comments on commit a24873d

Please sign in to comment.