Savolainen Sampo ha scritto:
> Hi,
>
> A short introduction is probably in order as I just subscribed to the
> list and to bring my proposal into context. My name is Sampo Savolainen
> and I work for the Information Centre for the Ministry of Agriculture
> and Forestry in Finland. We have decided to use WFS and WMS as the
> protocols to deliver spatial features and map images to our apps.
> Geoserver was chosen to be the WFS server and we have been working
> together with OpenGeo to strengthen the integration between Geoserver
> and Oracle.
Yep. I take the occasion to thank you for sponsoring the Oracle store
improvements as well as GeoServer changes needed to make it feasible
to work with big amounts of data in Oracle (native maxFeaure -> limit
support, being able to work without native bbox just to name a couple).
> Because of the nature of our applications, we need to impose strict
> authentication and authorization rules on the WFS layers. We are using
> our own authentication and authorization backend and my job is to
> integrate this system to Geoserver. My first attempt was a very involved
> and overly complex ServletFilter which had to analyze the requests and
> filter responses according to the users authorization information. This
> approach works but is clunky, error prone and performs sub-optimally. I
> now started work on another approach based on DispatcherCallback and
> DataAccessManager mechanisms.
>
> The basic flow is that the user authenticates out-of-band in relation to
> geoserver. After successful authentication, the user receives a token
> which he/she must present with each WFS request. To be compliant with
> standard WFS clients, I want this token to be presented as a GET
> parameter to all WFS services. My problem is that Geoserver does not
> know of this token when it describes its' services: the onlineResource
> fields in getCapabilities response messages, the schema locations in the
> responses to getFeature etc. etc. This can of course be handled with a
> ServletFilter which recognizes URLs in the responses and transforms them
> accordingly. However it is not an optimal solution.
The issue is that it's hard to perform streaming filtering and changing
of those back links, right? I think in a normal situation you end up
caching in memory a DOM.
As I suggested off line, I think this transformation can be done
via XSLT. It seems that Stax can be coupled with XSLT to make the
transformation streaming, thought I'm not sure if it can be used
with the xml libraries we bundle with GeoServer (e.g., specific versions
of Xalan and Xerces).
> What I'm suggesting is a callback system which is called whenever
> Geoserver creates URLs. Like DataAccessManager is called to check
> whether the current user can access a certain resource, this
> URLConstructionCallback would be called whenever a URL is constructed.
> It can then decide to modify the URL if necessary.
>
> I think this addition could prove useful not only to me, but it could be
> useful on a more generic level. In fact, Geoserver already has a need
> for such a system: "proxified urls". Currently there's a utility method
> to proxify URLs: org.geoserver.ows.util.RequestUtils.proxifiedBaseURL().
> This method seems to be called everywhere a URL pointing back to
> geoserver is created. I think this mechanism would be much better suited
> to a callback system.
Having people remember to use the callbacks every time seems a little
unlikely, but we can make a single proxifier method that looks for one
or more callbacks in the spring context. Something like:
RequestUtils.buildURL(String baseURL, String path, Map kvp, URLType
type) -> String
which internally would first proxify the requests, and then call in
order whatever url contruction callback is there.
> There's also a ReverseProxyFilter which I'm not
> that familiar with but it seems like it's doing the same thing. This
> callback system could remove the need for the filter altogether if I've
> understood its' purpose correctly.
ReverseProxyFilter is there to handle HTML transformation.
The theory behind it (and the fact it's disable by default) is that if
you have a HTML aware proxy GeoServer should not do anything and let
the proxy do its work (a sample of such thing is
thelibapache2-mod-proxy-html that is shipping with recent distributions).
XML backlinks explicit handling in code is there because we're
not aware of any XML aware proxy that would change the xml contents
on the fly, so we do it "built in".
>
> A rough sketch of the proposed API:
>
> public interface URLConstructionCallback
> {
> public enum URLType {
> EXTERNAL, // The link points outside Geoserver
> RESOURCE, // The link points to a static resource (image, ogc
> schema, etc.)
> SERVICE // The link points to a dynamic service provided by
> Geoserver (WFS, WMS, WCS, etc.)
> };
>
> public void constructUrl(StringBuffer url, Map kvp, URLType type);
> }
>
> The constructUrl() callback method could modify the base url and/or the
> key-value-pair map. The URLType parameter and Request, Service and
> Response objects (which are available through ThreadLocals via static
> methods, right?) would provide information about the function and
> context of the URL in construction.
Yeah, in your case if I understood it right you would add a KVP
parameter to the URL that is used to specify the auth token.
The dispatcher callback would put the param into a thread local that
would be then used by the url construction callback to modify the
URL.
> The kvp could be optional and we could allow GET parameters to be
> already present in the URL string. This could make the use of such API
> easier.
>
>
> The utility method for creating URLs would iterate the URL over spring
> registered callback objects:
>
> public String constructURL(String baseUrl, Map kvp, URLType type)
> {
> if (urlConstructionCallbacks == null ||
> urlConstructionCallbacks.size() == 0) {
> return appendGetParameters(url, kvp);
> }
>
> StringBuffer tmp = new StringBuffer(url);
>
> for (URLConstructionCallback callback : urlConstructionCallbacks) {
> constructUrl(tmp, kvp, type);
> }
>
> return appendGetParameters(tmp.toString(), kvp);
> }
>
> // helper methods could be created to shield using classes from
> importing the URLType enum.
> public String constructExternalURL(String baseUrl, Map kvp)
> {
> return constructURL(baseUrl, kvp, URLType.EXTERNAL);
> }
Ok, so the callback is actually allowed to change both the
url stringbuffer and the kvp map contents?
For proxy handling I guess we want to separate the
baseUrl form the path. For example, in a typical backlink you'd have:
base url: http://host:port:8080/geoserver
path: /wms
Thinking about it a bit more, I'm not sure it's really necessary to
pass around the base url explicitly... now that we have a thread
local representing the request we can access the base url at any
time from any piece of code.
Even the code that is not changing the URL to handle the proxies
could just be implemented as a url callback (one that changes the
url instead of the parameters).
Sounds good enough to me... what do others think?
Cheers
Andrea
--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Geoserver-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geoserver-devel