To chime in with my thoughts on this one:
I like the idea a lot. How we handle proxying urls is something i have
never been that happy with. So if I understand correctly (and to sum up)
what this is entails is:
1) coming up with the "mangle" method, RequestUtils.buildURL() or
constructURL(). I actually prefer the name "postMangleURL()" as it seems
more descriptive to what is actually occurring.
2) Coming up with an extension point (URLConstructionCallback). Again
for naming purposes something like "URLMangler" seems more descriptive.
3) Every call to "proxifyBaseURL()" gets replaced with "buildURL()" (or
whatever it gets called).
4) The impl of "buildURL()" does a extension lookup and calls every url
callback, and also explicitly invokes the Proxifying url callback.
As i understand it, this sounds good to me.
Open question is does this require a GSIP?
-Justin
Andrea Aime wrote:
> 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
>
>
--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.
------------------------------------------------------------------------------
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