Adding security restriction access
Right now the only way to restrict access to WFS stream is to handle it throught the Web Server (as with .htaccess on Apache ...), or to put a filtering proxy beetween WFS-T client and server.
To keep both performance and simplicity to deploy, it could be interresting to add security filter based on a role/password model, directly in TinyOWS for:
- the whole server
- a single layer (and if any all of their children layers)
- being able to say if access is restrict only for writing or also for read access, or even to discover the layer itself throught GetCapabilities/DescribeFeatureType
- on a geobbox extent
Configuration step must been kept simple enough in config file. The login/pass couples are for now set also in the config file.
Login and password have to be sent by the client as additionnal parameters in the GET URL. So don't imply to change anything client side. But definitly imply to be usefull to use https.
What's about to pass the REMOTE_USER to the DB? All authentication is done by the webserver with all modules available there. REMOTE_USER is secure, because no modification from outside is possible. It's transparent to the client. The DB can decide which tables, layers, rows are presented to this user.
Currently: The time consuming connect to the DB is currently avoided in FastCGI mode, otherwise the connect would be best to pass the user, as intended by the DB design. The config.xml or mapfile is also only read once, to save parsing time and it's not possible to reload them (as I know)
Changes: In a config-DB a table coud be specified which contains the DB-roles-users tuples. DB or tinyows could look up the role for the user (indexed->fast). Another table contains the role-layer relation in which the rights (select, insert, update,..) for this layer are saved. Here even a column could be specified if the queries should be extended by the role or username. With role or username, row based security would be possible at least for read-access. This column must be filtered that it can not be set from outside! GetCapabilities/DescribeFeatureType can look up which layers are visible, writeable by the current user. When the config is moving also in the DB, users could even create new layers on the fly: No parsing overhead, only a DB-query. In the config.xml (or mapfile) only the connect to the config-DB would be necessary. Everything else should go in the DB.
So each request generates max. 3 additional SQL-querys (getRole, getLayers/getConfigFromDB, getRightsColumn) Each individual user could see a complete different WFS, even the remote DB/WFS access can be limited this way.
Chages in the code: Read config from DB (here in is the most work) Parse CGI for the REMOTE_USER variable (getEnv()) For each DB access look up the column and if present, lookup the role if necessary (at approx 10-15 positions)
If this as too much change in the config of Tinyows, then the access could be also directly incorporated in the config with usernames, @groups. A column-name which contains the username in the query. A flag if group or user should be used in queries. And a group-user-table in the DB to look up the roles.
Or to be DB-dependend but use the full power of the DB in postgresql: SET SESSION|LOCAL AUTHORIZATION ...
An this is don only to prevent that the connectDB is calld for each request.
Thanks for you input Stephan !
I like the idea to keep things simple, so if we use REMOTE_USER we could let Web Server deal with the auth part, and even also let database deals with the rights part.
But i don't see how you deal with row access (for instance allowing a specific user to write in a relation only if it's inside a defined bbox (or an another feature).
Sorry, I mixed three different things. The first is REMOTE_USER as an authenticated username which would be good to use it in tinyows and possible pass it to the DB. The second is layer security, which tinyows could simply do by checking if the user has access to this layer. This can be configured in the config file. The third is row security. This would need additional columns to the tables indicating which role is allowed to which operation. The distinction between layer security and row security is important. Layer-security can be done directly inside tinyows without DB help. I saw some proxies which filter the userequests to some spatial extent, like BBOX, but I think this is more an application problem than a DB problem. If the DB has access to the username then spatial filtering is also possible and the "mask" can be everything. (for exampe the user is allowd to add his GPS-tracks only to areas which are inside "public parks".)
I'm just trying to get a demonstrator running, but this might still take some days...
If at least parts of the config would be stored in the DB the dynamic creation of new layers would be possible. But this is another topic...
Humm adding extra columns, imply that a specific app (i.e TinyOWS) would change the database data model. Lot of users would not afford such a thing...
A config file approach seems (to me) a better way to provide row security...