This page last changed on Jul 31, 2008 by igrcic.

Overview

Allowing per layer security to complete the security offering started with service layer security
Motivation
Proposal
Backwards Compatability
Feedback
Voting
Links

Proposed By

Andrea Aime

Assigned to Release

This proposal will be implemented by 1.7.0-rc1 release

State

Under Discussion, In Progress, Completed, Rejected, Deferred

Motivation

At the moment GeoServer only sports OGC service and service method security, many real world use cases need more granular control based on the data contents, and thus a layer based security.
This proposal handles layer wide security only, per feature or per attribute security is out of the scope.

Proposal, user view

This project is to enhance the security subsystem in GeoServer to allow namespace-based and layer-based authorization for read/write access. The description of this work uses the term 'layer' to refer to either a GeoServer feature type or coverage.

Access permissions will be configurable by entries in a the GEOSERVER_DATA_DIR/security/layers.properties property file, following the syntax already available for service level security:

namespace.layer.permission=ROLE_1[,ROLE_2][, ...]]

where:

  • namespace indicates the name of the namespace. The wildcard * is used to indicate all namespaces (i.e. global scope).
  • layer is the name of a feature type or coverage. The wildcard * is used to indicate all layers in the namespace.
  • permission indicates the type of access permission
    • 'r' - indicates read access permission
    • 'w' - indicates write access permission
  • ROLE#_ are the names of roles (defined in the user.properties file). The wildcard * is used to indicate the permission is applied to all users, including anonymous users.

Rules:

  • Each entry must have a unique combination of namespace, layer, and permission values.
  • If a permission at the global level is not specified, global permissions are assumed to allow read/write access, i.e. ..r=* and/or ..w=*
  • If a permission for a namespace is not specified, it inherits permissions from the global specification.
  • If a permission for a layer is not specified, it inherits permissions from it's namespace specification.
  • If a user belongs to multiple roles, the least restrictive permission they inherit will apply.

Once security is in place:

  • the web administration tool, as well as all the demos, will only display namespaces and layers that the current user is allowed to see;
  • all the OGC services will handle out only the layers the user can see, if the current user does not have write permission, all attempts at writing will fail

To ease up implementation, GeoServer will behave as if the unauthorized layers are unavailable or physically read only. This also allows for better security (throwing an exception about the layer not being accessible discloses the layer is there).
Any attempt to access a secured layer with not enough rights will be logged for administrators to evaluate security threats and for debugging purposes.

Example configuration protecting a single namespace and a single layer

The following entries demonstrate configuring GeoServer so that it is primarily a read-only server.

GEOSERVER_DATA_DIR/security/layers.properties
*.*.r=*
*.*.w=NO_ONE
private.*.r=TRUSTED_ROLE
private.*.w=TRUSTED_ROLE
topp.congress_district.w=STATE_LEGISLATORS

in this scenario here is the map of roles to permissions:

  private.*
topp.* topp.congress_district (all other namespaces)
NO_ONE (no access) w (no access) w
TRUSTED_ROLE r/w r r r
STATE_LEGISLATURES
(no access) r r/w r
(all other users)
(no access) r r r

Example configuration for locking down GeoServer

The following entries demonstrate configuring GeoServer so that it is locked down.

GEOSERVER_DATA_DIR/security/layers.properties
*.*.r=TRUSTED_ROLE
*.*.w=TRUSTED_ROLE
topp.*.r=*
army.*.r=MILITAR_ROLE,TRUSTED_ROLE
army.*.w=MILITAR_ROLE,TRUSTED_ROLE

in this scenario here is the map of roles to permissions:

  topp.* army.* (all other namespaces)
TRUSTED_ROLE r/w r/w r/w
MILITAR_ROLE r r/w (no access)
(all other users) r (no access) (no access)

Example Configuration for something more complex

The following entries demonstrate configuring GeoServer with global-, namepace-, and layer-level permissions.

GEOSERVER_DATA_DIR/security/layers.properties
*.*.r=TRUSTED_ROLE
*.*.w=NO_ONE
topp.*.r=*
topp.states.r=USA_CITIZEN_ROLE,LAND_MANAGER_ROLE,TRUSTED_ROLE
topp.states.w=NO_ONE
topp.poly_landmarks.w=LAND_MANAGER_ROLE
topp.militar_bases.r=MILITAR_ROLE
topp.militar_bases.w=MILITAR_ROLE

in this scenario here is the map of roles to permissions:

  topp.states topp.poly_landmarks topp.militar_bases topp.(all other layers) (all other namespaces)
NO_ONE w r (no access) w w
TRUSTED_ROLE r r (no access) r r
MILITAR_ROLE (no access) r r/w r (no access)
USA_CITIZEN_ROLE r r (no access) r (no access)
LAND_MANAGER_ROLE r r/w (no access) r (no access)
(all other users) (no access) r (no access) r (no access)

Note: The topp.states.w=NO_ONE is not needed, because this permission would be inherited from the global level, i.e.

*.*.w=NO_ONE


Example of an Invalid Configuration File

The following set of entries would not be valid because the namespace, layer, permission combinations of the entries are not unique.

topp.state.rw=ROLE1
topp.state.rw=ROLE2,ROLE3

Proposal, implementation

The current security integration uses an Acegi based filter to perform authentication, Acegi then puts the result of the authentication in a ThreadLocal variable that can be accessed using SecurityContextHolder.getContext().getAuthentication(). This is already leveraged by the dispatcher, that performs the necessary service level checks.

The idea is to replicate the same checks at the catalog level, by introducing a security wrapper as depicted in the following diagram:

The catalog wrapper would forward all calls to the actual catalog, and then filter out the results comparing them with the actual access level of the current user, in particular:

  • by removing all layers that the user is not authorized to see
  • by wrapping FeatureTypeInfo if the user is not authorized to write them (coverages are at the moment read only, so this does not apply)

This leaves most of the GeoServer code completely security unaware, making development and maintenance easier compared to a solution that would move the security checks onto the services themselves.

The catch is, in order to wrap the catalog, it must be split into an interface and an implementation. This is possible, and it's going to be introduced along with the new configuration proposal, so this one will be implemented as soon as the new configuration proposal lands on trunk

Relationship with service layer security

GeoServer 1.6.0+ sports service level security as described in the user guide.
The data level security builds on top of it, reusing user and role definitions found in $GEOSERVER_DATA_DIR/security/users.properties.
Each request will be subject to both security checks, according to the following workflow:

  • the user gets authenticated using Acegi integration (at the moment, either form or HTTP basic authentication)
  • the service level security gets checked by the dispatcher, if access is denied, the request ends
  • the service will attempt to access the catalog, each of those attempts will be subjected to data level security restrictions

So, to sum up, in order to successfully execute an OGC service call the user will have to be allowed to execute the requested service method and to access the data specified in the request.

Feedback

This section should contain feedback provided by PSC members who may have a problem with the proposal.

Backwards Compatibility

The proposal has not backwards compatibility issues, the default layers.properties file will be empty, meaning all layers can be accessed by everyone.

Voting

Andrea Aime: +1
Alessio Fabiani: +1
Justin Deoliveira: +1
[~jgarnett]: +1
[~sfarber]:
[~roba]:

Links

JIRA Task


implementation.gif (image/gif)
implementation.gif (image/gif)
Document generated by Confluence on May 14, 2014 23:00