[Geoserver-devel] Using servlet filters and slds to provide security?

Hey folks,

I'm embarking on a project that will use geoserver as a wms
interface. There are a few simple shapefiles representing the bounding
boxes of various ecology field studies. The problem is we need to
limit public access to certain approved features while authenticated
users are able to view everything.

We've created a servlet to determine the user's permissions and
construct the appropriate SLD+filter document on-the-fly. We can
easily point the mapbuilder client to this SLD factory servlet via a
WMS request. But this doesn't really provide the needed security.. a
user could simply strip out the &SLD=... and have full access.

I've been looking into servlet filters as a way to enforce that the
SLD is applied. I can set up a basic filter but I'm having trouble
altering the incoming ServletRequest. HttpServletRequest has a
getParameter() method but not a setParameter() :frowning:

The psuedo code for what I'd like to do :

if request contains an sld:
  remove the requested sld parameter and replace with the sld factory url
else:
  append an sld parameter pointing to the sld factory

I'm trying to avoid altering the core geoserver classes to ensure we
have an easy upgrade path in the future. I'm hoping this servlet
filter method would ensure that every wms request be filtered
according to user's permissions.

My questions:
1. Is this even a good approach or are there other ways to accomplish this?
2. Anyone have any hints or examples for altering the incoming request
parameters?

Thanks,
--
Matt Perry
perrygeo@anonymised.com
http://www.perrygeo.net

Matt,

One way could be to set up a servlet 'proxy' for geoserver.

I.e., have a stock geoserver running on a private ip (or only on localhost). You'd configure this at the system level, or at the servlet-container level (if you only wanted it to run on localhost).

Then set up a *different* servlet container that faces the public. Have an end-point like '/geoserver-proxy/wms' which simply examines the incoming request, determines access based on http sessions (for login/authentication), time of day, or whatever else you wanted to program, and then either rejects/modifies/connects the request through to the private, hidden back-end geoserver.

The proxy would do something like:

doGet() {

if (checkPermissionsAreOk()) {
  URL forwardedURL = copyThisRequestButSubstitutePrivateGSURL();
  InputStream realResponse = forwardedURL.openConnection().getInputStream();
  OutputStream clientResponse = response.getOutputStream();
  //now just hook the geoserver inputstream up to the client outputstream. while loop, pipedStream, or whatever.
}

There's code much like this (only without any authentication) here:

http://svn.codehaus.org/mapbuilder/trunk/mapbuilder/mapbuilder/server/java/src/mapbuilder/ProxyRedirect.java

I guess they use the commons-httpclient library though.

This would allow you to have a stock geoserver, thereby providing you a simple upgrade path, while also allowing you to put any further custom logic into your authentication that you needed.

--saul

My questions:
1. Is this even a good approach or are there other ways to accomplish this?
2. Anyone have any hints or examples for altering the incoming request
parameters?

Saul,

Thanks for the response,

On 8/17/06, Saul Farber <Saul.Farber@anonymised.com> wrote:

One way could be to set up a servlet 'proxy' for geoserver.

I.e., have a stock geoserver running on a private ip (or only on
localhost). You'd configure this at the system level, or at the
servlet-container level (if you only wanted it to run on localhost).

This was our original idea, but for various reasons (mostly because we
also need the geotools jars for other parts of our app) we're aiming
to run everything in the same web-acessible servlet context. This will
be distributed to our users as a single .war with geoserver seamlessly
integrated.

Just to give everyone a bit of background on our project, I'm working
on Metacat (http://knb.ecoinformatics.org/software/metacat/), an xml
database application for storing and retrieving EML and FGDC metadata
documents. Our lateset goal is to use geoserver/mapbuilder to provide
a front end for visualizing and quering the spatial components of the
metadat docs.

Today I started researching the Spring framework and plugin
architecture of the geoserver 1.4 branch. I'm considering using an
AbstractService to provide a security-enhanced wms dispatcher.. or
something like that.. I haven't really delved into it fully yet :wink:

I'd really like to hear everyone's ideas on how to best implement a
security filter on top of geoserver.. servlet filters ... some sort of
generalizable sld-based filtering plugin? Any ideas would be much
appreciated.

Thanks again,
--
Matt Perry
perrygeo@anonymised.com
http://www.perrygeo.net

Um so you know to use Spring AOP to wrap you security checks around the methods needed right? This advantage in addressing security was one of the motivations in choosing Spring ... most spring books use a security check as an example of AOP. I imagine you could find a library that provides a security bean somewhere on the web, and then either teach the serivce object to delegate to it (boo hiss) or use the security bean for a pre check on the response handler code. The same approach can be used with the catalog for data level restrictions (ie check on datastore access), and on query if you need to lock down attributes (precheck the query before use).

Cheers,
Jody

Saul,

Thanks for the response,

On 8/17/06, Saul Farber <Saul.Farber@anonymised.com> wrote:
  

One way could be to set up a servlet 'proxy' for geoserver.

I.e., have a stock geoserver running on a private ip (or only on
localhost). You'd configure this at the system level, or at the
servlet-container level (if you only wanted it to run on localhost).

This was our original idea, but for various reasons (mostly because we
also need the geotools jars for other parts of our app) we're aiming
to run everything in the same web-acessible servlet context. This will
be distributed to our users as a single .war with geoserver seamlessly
integrated.

Just to give everyone a bit of background on our project, I'm working
on Metacat (Metacat Administrator’s Guide — Metacat 3.0.0 documentation), an xml
database application for storing and retrieving EML and FGDC metadata
documents. Our lateset goal is to use geoserver/mapbuilder to provide
a front end for visualizing and quering the spatial components of the
metadat docs.

Today I started researching the Spring framework and plugin
architecture of the geoserver 1.4 branch. I'm considering using an
AbstractService to provide a security-enhanced wms dispatcher.. or
something like that.. I haven't really delved into it fully yet :wink:

I'd really like to hear everyone's ideas on how to best implement a
security filter on top of geoserver.. servlet filters ... some sort of
generalizable sld-based filtering plugin? Any ideas would be much
appreciated.

Thanks again,
  

Jody,

On 8/17/06, Jody Garnett <jgarnett@anonymised.com> wrote:

Um so you know to use Spring AOP to wrap you security checks around the
methods needed right? This advantage in addressing security was one of
the motivations in choosing Spring ... most spring books use a security
check as an example of AOP.

Ahh. Good to know. I just downloaded geoserver 1.4m1 this afternoon
and started researching the new spring architecture so I'm not quite
up to speed yet! It seems like the move to spring will provide a much
more flexible and extensible architecture and I look forward to trying
it out.

I imagine you could find a library that
provides a security bean somewhere on the web, and then either teach the
serivce object to delegate to it (boo hiss) or use the security bean for
a pre check on the response handler code. The same approach can be used
with the catalog for data level restrictions (ie check on datastore
access), and on query if you need to lock down attributes (precheck the
query before use).

The 'pre check' seems like a good idea.

Ideally I just want to check the user's session, construct an sld to
block access to certain features within the dataset, append the sld to
the incoming request and let geoserver handle the rest. It gets a bit
tricky when your access contraints are on a feature level as opposed
to entire datasets !

Thanks for the advice. I'll keep digging into it and let you know what
I come up with.

-matt

Cheers,
Jody
> Saul,
>
> Thanks for the response,
>
> On 8/17/06, Saul Farber <Saul.Farber@anonymised.com> wrote:
>
>> One way could be to set up a servlet 'proxy' for geoserver.
>>
>> I.e., have a stock geoserver running on a private ip (or only on
>> localhost). You'd configure this at the system level, or at the
>> servlet-container level (if you only wanted it to run on localhost).
>>
>
> This was our original idea, but for various reasons (mostly because we
> also need the geotools jars for other parts of our app) we're aiming
> to run everything in the same web-acessible servlet context. This will
> be distributed to our users as a single .war with geoserver seamlessly
> integrated.
>
> Just to give everyone a bit of background on our project, I'm working
> on Metacat (http://knb.ecoinformatics.org/software/metacat/), an xml
> database application for storing and retrieving EML and FGDC metadata
> documents. Our lateset goal is to use geoserver/mapbuilder to provide
> a front end for visualizing and quering the spatial components of the
> metadat docs.
>
> Today I started researching the Spring framework and plugin
> architecture of the geoserver 1.4 branch. I'm considering using an
> AbstractService to provide a security-enhanced wms dispatcher.. or
> something like that.. I haven't really delved into it fully yet :wink:
>
> I'd really like to hear everyone's ideas on how to best implement a
> security filter on top of geoserver.. servlet filters ... some sort of
> generalizable sld-based filtering plugin? Any ideas would be much
> appreciated.
>
> Thanks again,
>

--
Matt Perry
perrygeo@anonymised.com
http://www.perrygeo.net

Matthew Perry wrote:

The 'pre check' seems like a good idea.

Ideally I just want to check the user's session, construct an sld to
block access to certain features within the dataset, append the sld to
the incoming request and let geoserver handle the rest. It gets a bit
tricky when your access contraints are on a feature level as opposed
to entire datasets !

That is an interesting approach (one I had not considered), I am looking to see how SLD ENV variables work
and if we can figure out how to pass such things as DPI (or user credentials) into the SLD
document for conditional evaluation.

Wonder if we could make a vendor specific extention to GetMap to allow clients to pass
in *their* DPI (or associate it with a session) - this would enable me to make a series of tile
requests to the WMS when printing, or working with large monitors. Possibilities!

Thanks for the advice. I'll keep digging into it and let you know what I come up with.

Cool, we are *very* interested in your experience as this transition to Spring is a work in progress, if
you have any suggestions speak up early (and often).

Jody