Hi all,
I started writing this email before I realized how long it would be, so I have
copied what I was originally going to say into
http://geoserver.org/display/GEOS/GSIP+25+-+Pluggable+Authentication+Mechanisms
on the wiki. This is just me musing on bugs
(http://jira.codehaus.org/browse/GEOS-1579 and GEOS-2000) so there's not a
specific use case driving it, but I think now (with GS 2 coming up) is a good
time to give some serious forethought to security configuration.
-David Winslow
I have been doing some thinking about pluggable security systems in GeoServer.
(inspired mostly by http://jira.codehaus.org/browse/GEOS-1579) Right now we
have at least two "sections" of GeoServer which are guarded by different
authentication mechanisms, but share a database for authorization. Everything
is configured in an XML file that ends up in a JAR inside a WAR which doesn't
really lend itself to end-user customization. That is, user-configurable
pluggable security systems, as we already have a pretty flexible system with
Acegi. However, right now all that's available to users ("users" at the
moment being those willing to modify web.xml and some properties files by
hand) is the option to assign roles and passwords to users, and to restrict
either layers (if we include Andrea's recent work) or service methods to a
subset of those roles. That is, there are three configuration sections
relevant to security:
<users.properties>
defines user, password, list of roles
<layers.properties>
defines layer, read/write, list of allowed roles
<service.properties>
defines service, operation, list of allowed roles
There's also a suggestion (http://jira.codehaus.org/browse/GEOS-2000) to have
a properties file defining access rules based on url and http method (so we
can restrict operations in the REST API), so I'll add:
<rest.properties>
defines URL, HTTP method, list of allowed roles
What's not at all user-configurable right now is the authentication mechanism
used to find out what user is accessing GeoServer. We just have the following
hardcoded:
for the admin console, use an HTTP cookie, redirecting to a form if the cookie
is not found OR if the user is not in the required role (which is also
hardcoded).
for the OWS services, use HTTP basic auth, returning a 401 error when
permission is denied.
for rest stuff, no authentication is implemented.
So we have GeoServer kind of divided into security 'zones;' the admin console
is one; the OWS services are another, and the REST stuff (or maybe just the
rest) constitutes a third. It might be nice for users to be able to define
these zones themselves, but right now they seem pretty radically different in
structure so that should probably wait until we have enough use cases to
better define them. Each zone has not only its own authentication mechanism,
but also its own type of restriction rules:
admin console: it's just 'you have to be in ROLE_ADMIN'
OWS service: layer+access or service+method -> list of allowed roles
REST API: URL+HTTP method -> list of allowed roles
For a first stab at pluggable authentication mechanisms, maybe it's sufficient
to just let users set the mechanism for each of these zones individually; it
could be as simple as including a set of parameters in web.xml that are
expected to be class names of authentication plugins, something like
<context-param>
<param-name>OWS_AUTHENTICATOR</param-name>
<param-value>org.geoserver.acegi.HttpBasicAuthenticator</param-value>
</context-param>
Bean names could work here as well. The default values would just emulate the
current authentication system, and the current properties files would still be
used for the authorization tasks.
In the long run though, it may be that users would like to be able to define
their own zones (example use case: multiple REST plugins are provided that
need to provide access to different clients; so you want to allow two
different authentication mechanisms to clients using different subsets of the
REST API). Since a zone as I've defined it is just a subset of GeoServer's
functionality combined with an authentication mechanism and a type of rule, we
could probably have just a file zones.properties that looks something like:
<zones.properties>
#prefix[,prefix...]=authenticator,filter[config[,config]]
/config/=org.geoserver.acegi.FormAndCookieAuthenticator,org.geoserver.security.AdminOnlyFilter
/ows,/wfs,/wms,/wcs,/wfsv=org.geoserver.acegi.HttpBasicAuthenticator,org.geoserver.security.MethodAndLayerFilter(service.properties,layers.properties)
/rest/=org.geoserver.acegi.HttpBasicAuthenticator,org.geoserver.security.HttpMethodFilter(rest.properties)
Both of the JIRA tasks I linked in this message are marked for backporting to
1.6.x, so adding zones.properties as a required configuration file is not a
great option in the short term (adding just the context parameters to web.xml
is better, since we can more easily code in the default values, but still not
fantastic). But I think that we should try and think about extensibility for
the security configuration as well as the catalog for 2.0.