Role Based Security & ArcGIS Server

Posted by Dave Bouwman | Posted in ArcGIS Devt, ArcGIS Server, ArcMap, Geodatabase | Posted on 30-04-2007

1

I recently recieved an email from a reader asking about role based security
& ArcGIS Server. Specifically they were interested in restricting access to
columns, based on the user’s credentials.

I’d been doing some thinking on
similar issues related to row based edit permissions, and I thought I’d share my
ideas on possible solutions to these problems.

Fine Grained Access Permissions

Essentially, you can’t use the DBMS security capabilities to restrict user
access to columns or rows because ArcSDE does not support security at this fine
grained level (FeatureClass, ObjectClass or FeatureDataset only). There may be
some hacks, but as far as I know nothing like this is supported directly.

Next, and possibly more important, regardless of how you actually create the connections (i.e. store the
connection properties in the MXD file, or use pass-through authentication and
grant the SOC process permission to connect into the database) all interactions
with features are done as the SOC Service user. The identity of the front end
user  is not passed back to the SOC. Thus, regardless of who is running the
application, the SOC identity is always the same. The diagram below shows how far you can pass back the end user’s identity (assuming you setup impersonation in your web app).

 

The SOC always runs as the SOC Service user – so any use of the end user’s identity to control any sort of access is not going to work.

Possible Solutions – Restricting Access to Columns

There are a variety of ways to tackle this, but none are particularly
flexible – you will need to define the roles up front, and then setup the
application to respect those roles explicity. Adding additional roles will
require code changes. Four options come to mind

1) Let the SOC return all the data and apply the permissions in the client
application. This is not a bad solution if you control the web app. It basically
means re-writing a lot of the out of the box tools so that they will respect
this additional business logic.

2) Setup the spatial data so that it has the minimal set of field that all
users can see (including ObjectId). When doing an inquiry, the web app would get
the base set of fields from the featureclass, and then use the ObjectId  to run
a second query against a multi-version view to retreive the other “secured”
 attributes. There would be a multi-version view for each role in the
application, and the columns would be restricted as needed. The application
logic would need to handle the mapping of the users role to the correct
view.

3) Use Spatial Views. Similar to #2, but the SOC would load layers based on
the user’s role, and the layers would actually be Spatial Views with only the
columns that are visible for the particular role of the user. I suspect this
would be slower than the previous two options, as the SOC would need to load
layers all the time, but if the application is using a non-pooled SOC anyhow, it
may not bemuch more of a performance hit – just start with a minimal map (just
the layers which do not have any restrictions on them). The upside is that you
can likely use most of the out of the box tools since the column restrictions
are being applied by the view, at the ArcSDE level. Another upside of this model
is that the restricted data is never available – either in the SOC, or in the
web application tier.

4) Similar to #3, you could separate out the restricted fields into separate
tables, and apply joins on the fly. Same benefits as #3, but you’d still want to
work with non-pooled SOCs. Not sure how well this would play with the out of the
box tools, but it may be ok.

I’m sure there are other options, but I suspect they are all variations on this same theme. If the application was super simple (like 1 ID tool), you could just limit the fields returned by setting the IQueryFilter.SubFields property.

Row Based Edit Permissions

For our applications, there are typically business rules which restrict the
area in which a user can edit features, and related attribute tables. In the
past we have implemented this logic in feature class extensions. In the
extension, we simply get the current principal (the user’s Windows Login
identity) lookup their access permissions from our repository and allow/block
the edit. We have logic in the extension which allows for editing of shared boundaries (which I believe is one of the issues with implementing this sort of logic at the DBMS level)

This works just fine for Desktop and ArcEngine applications, but is more
problematic for web applications. As I noted at the start of this post, all
connections into ArcSDE from ArcGIS Server run as the SOC user. Thus we have a
problem – if we apply a class extensions to the geodatabase, it’s logic always
fires – regardless of the client appliction. But, if all the edits from everyone using the web app
effectivly run in the same context, (agssoc or whatever you call it on your system), then
this logic is both moot, and a waste of processor time. But we still want to use this logic for the desktop apps, so we had a bit of a problem.

Our solution is to create feature class extensions which are themselves
extensible. Basically we use  the Provider
Model
to add in various security providers at run-time. When the class extension spins up, it uses the ConfigurationManager
to check the configuration file (ArcMap.exe.config for desktop, web.config for
web apps) for “SecurityProviders”. In the desktop apps, there will be a provider
configured, the class will be instantiated, and the logic applied to all
the edits. In the web app, we do not configure a security provider, thus there
is no logic applied. 

This still begs the question of “how does the row based edit permission get
applied in the web app?”. At this time, there is no (easy) way to pass the user
identity back into the SOC, let alone get the SOC to impersonate a user such
that the class extension would be running in the context of the front end
user. So, for now, the answer is – the web application must handle this logic
itself. While this is not idea, at least the class extensions can be used in the
desktop apps – which is where the vast majority of the edits will occur
anyhow.

EDN Search: IObjectClassExtension….

Posted by Dave Bouwman | Posted in ESRI | Posted on 30-04-2007

2

Recently ESRI has been taking surveys as to what they should be focusing on @ support.esri.com. In their “early results” posting, they are apparenly taking notice of the limited search capabilities on the site. Just wanted to add that the search on EDN is also in need of some love.

In prepping another post, I went to the “Current Library” page, and typed in “IObjectClassExtension” – which returned a whole mess of things which make some reference to IObjectClassExtension, and it actually hilights the term in BOLD, but it did not have a link to the actual page that describes the interface.

I changed the search setup a little, and got all 32 references back on the same page – the interface was at #24. I’m not sure how much more explicit I can be with this. Please please please work on making this search better!

Incidentally, Google nails it (ok, it’s the 9.1 Java doc, but at least it’s the interface!). Instead of trying to tweak whatever search engine they have, maybe they could work with Google to ensure that the site is accurately and regularly indexed, and ensure the site:edn.esri.com <search> works (currently this does not return any results)

DevSummit Podcast is up….

Posted by Dave Bouwman | Posted in Dev Summit, ESRI | Posted on 29-04-2007

0

Where did April go? Anyhow – I’m finally getting my head above water, and was catching up on my blog reading when I noticed that James posted a link to the podcast interview I recorded at the 2007 ESRI Developer summit.

For those interested, here is a direct link to the MP3. And kudos to whoever edited it, since it sounds much more coherent than I recall!

I’m thinking the next few weeks will be some what sane, and I’ve got a few blog posts started, so things should be back to normal shortly.

ArcGIS Server: PreferredTileHeight/Width…

Posted by Dave Bouwman | Posted in ArcGIS Server | Posted on 05-04-2007

7

So I was just playing around with a simple ArcGIS Server app, seeing what I
could do to reduce the amount of data sent to the client and at the same time
speed things up a little. I took a look at the PreferredTileHeight
and Width properties of the Map control. By default, these values are set to
zero, which means that each tile will be the size of the entire map control.
But, if you have a pretty large map, a small pan can result in a lot of data
being sent back to the client.

[I should note at this point that for this use case, we cannot build a tile
cache - the data is too dynamic and the cache cooking process is too slow - maybe at 9.3 when the cache can be cooked dynamically.]

Supposing you have an 600 x 600 map canvas, and since you’ve got imagery,
it’s set to 24bit PNG. In my testing, this results in a ~700kb image (example here) on average.
So – if the user just pans down and right a little, ArcGIS Server will be
creating and sending three 700kb images for a total of  2.1 Mb of data being
transferred. Not bad on a LAN, but a few users like this can overwhelm at T1
pretty quickly.

My idea was to set the PreferredTileHeight and PreferredTileWidth to some
smaller value – say 200 x 200. In that case, a small pan would result in (at
most) 7, smaller tiles (example) being sent across, and since these averaged 100kb each,
it would be 1/3rd the data sent across the wire as compared to the 600 x 600
tiles. The end result was a much smoother panning experience for the map service
with the imagery (occasionally there were “tile holes” though – not sure
why).

Where things got interesting is when I switched to a different map service
which was just vectors. More specifically this service has feature labels. It seems that the rendering engine does not know that it’s sending the data
as a block of tiles – thus it renders a label for each feature in each tile, resulting in repeated labels across the image. This makes sense, but ends up looking a little weird…

The
TileCache gets around this by rendering much larger “super tiles” which are then
cut up into the smaller tiles – and this avoids the multiple-labelling
issue. Anyhow – if you are thinking about using a non-zero value for PreferredTileHeight / Width, watch out for this.