关于如何在你的Web项目中实现对空间数据访问权限的控制(一)
Wednesday, 23 JUNE
近来一直在研究关于如何在我的WebGIS项目中实现对空间数据(已发布在GeoServer上)进行权限管理的问题。虽然到目前为止没能找到一个完美的解决方案,但通过这些天的学习与查阅资料,思路上多少有了一些进展,因此记录下来,做一个简单的小结。
1-GeoServer中的Security模块
GeoServer是一个基于J2EE基础实现的,允许用户共享和编辑地理空间数据的GIS应用服务器。——FROM GeoServer官方介绍。
其实,GeoServer的本质是一个基于JAVA实现的Web项目工程,我在项目中使用的GeoServer是一个War包版本,直接将其copy到/%TomcatHome%/WebAPP/路径下,启动Tomcat,GeoServer就如同你自己的Web项目一样,被部署在了Tomcat中。当GeoServer被部署完成后,你可以通过http://localhost:yourport(你的端口号)/geoserver进入GeoServer的控制面板。
在控制面板的左侧菜单栏中,你很容易能够找到关于GeoServer的Security设置。接下来我将简单地介绍一下对已经发布在GeoServer上的资源进行权限分配的相关概念,为了避免这篇博客成为实验报告,我会尽量减少实际操作部分的描述,主要介绍Security模块的结构与原理。
1-1 角色
在GeoServer中,角色由三个部分组成:name/parent role/key-value Pairs,其中parent role【父角色】利用了继承的概念,使得每个角色都可以拥有一个父元素,子角色能够继承父角色的所有权限,比如说某个角色A,A_a是A的子角色,A所拥有的所有权限,都能够被A_a继承,但A不一定拥有A_a的所有权限,可以理解为,二者是一个递进的关系,父元素能够访问一定权限的资源,子元素的私密性程度更高,在父元素的权限基础上,能够拥有更多的资源访问权力。
任何系统安全模块的实现都是基于分角色授权的模式。GeoServer也不例外,在GeoServer中,角色服务(role service)主要由以下三个方面实现:
- 角色表
- 授权机制
- GeoServer系统角色与应用角色之间的映射关系(包括了管理员、角色分组)
其中角色表与授权机制都和普通的安全模块一样,你可以通过控制面板中可视化设置新的角色,并将其分配给不同的用户。而GeoServer中的角色与你所设置的角色之间的关联是GeoServer角色服务的关键部分,因为只有当你所新建的角色与系统角色映射关联之后,才能够获得管理GeoServer中数据的权限。
在GeoServer中,角色映射的配置方式主要包括以下两种:
- XML (默认方式)
- JDBC 通过JDBC,针对数据库中的用户表进行权限分配(推荐方式)
一般情况下,你只需要在GeoServer控制面板上的菜单栏中选中Users/groups/Roles一栏,在相应的位置进行设置就可以实现role service的新建、修改和激活,如你需要直观地查看XML配置文件的结构,可以通过访问/%GeoServerHome%/data/security/role/{yourRoleServiceName}即可看到你设置的相关角色分配情况。
PS: 在该路径下,一共有以下三个文件:
- Config.xml: 将本地角色与系统的角色相互映射
- Roles.xml: 设置角色种类,为用户分配角色信息
- Roles.xsd: 定义service的实现模式
1-2 用户认证 Authentication
前面的部分基本上围绕着角色,用户,用户组等概念对GeoServer的授权方式进行简单介绍。但一个完整的用户权限子系统应该同时具备两个关键内容:授权和认证,所以接下来我们一起来看看GeoServer中的用户认证(Authentication)方式。
这是左侧菜单栏中Authentication-add new authentication filter中配置界面的部分截图,从截图中我们可以看出,GeoServer提供了很多种认证方式,其中包括J2EE、Form表单、HTTP Header验证等等,其中GeoServery以Form表单认证作为默认方案,具体流程如下图所示
(图源来自于http://docs.geoserver.org/stable/en/user/security/usergrouprole/interaction.html):
从图中我们能够很明显的理解GeoServer进行用户认证的大体流程,主要依托于User/Group Service和Role Service两个服务进行授权和认证,在GeoServer平台上实现了GeoServer工程中的权限控制与管理。
1-3 认证链
前面1-2节简单介绍了一下用户认证的基本概念和流程,其实在GeoServer的权限功能实现过程中,有一个非常重要的概念——认证链,这是理解整个security认证机制的关键。
所谓认证链,Authentication chain,即一种处理请求并申请相应认证的机制,其中认证机制主要包括以下几种:
- Username/password:在外接用户数据库中查找用户信息
- Browser cookie:在浏览器缓存Cookies中查找之前的认证记录
- LDAP:根据LDAP数据库进行认证
- Anonymous:无需认证
多级权限认证机制能够在GeoServer的一次运行中分别被激活:
从上图我们可以看出,在请求进入dispatchServlet之前,GeoServer首先对请求进行认证链的过滤,请求逐个通过认证链上的每一个机制,如果任意一个认证机制能够成功与请求匹配,则将请求交还到正常请求处理的路径上,分发到合适的handler上,否则返回错误信息401.
实际上,认证链过程是由两个链组成的:
a filter chain(过滤链):请求是否需要认证 →不需要→ 直接进入处理请求流程
↓
需要
↓
A provider chain(规则链):请求与那个权限认证能够匹配
PS: Filter chain过滤链存在的意义在于:
- 从request中收集用户证书
- 能够处理例如:登出(logging out)和Remember Me浏览器缓存设置等问题
- 管理Session
- 帮助规则链接受一些无需认证请求,减少请求负荷
值得注意的是:不同的Filter chain能够处理不同种类的请求,因此管理员能够为不同的用户设置相应的过滤链,需要注意的是,如果同时有多条过滤链符合请求的时候,仅取第一条符合要求的过滤链。
1-4 OWS && REST Services
前面讨论的是对角色认证后,用户角色的状态变化,而用户角色认证的结果会影响到用户在应用中所拥有访问资源和进行操作的权限分配。接下来要介绍的就是基于OWS (OpenGIS_WebService)and REST service下的认证流程,这两种风格的服务并没有session这样一个概念,所以权限认证体系要求客户端为每一次请求提供证书,但如果session存在于服务器端,则session能够用于认证。
1-4-1 OWS Service的认证链
-
Session:处理整合session
-
Basic Auth:从HTTP header中提取权限认证证书(Username && passwords)
-
Anonymous:处理匿名访问【游客】
1-4-2 WMS的认证链
具体流程描述:
Ⅰ GetCapabilities request
Ⅱ GetMap request for a secured layer
如上图,Basic Auth被触发,判断是否登陆,如果仍是匿名登陆(Anonymous),则返回给用户HTTP 401代码,跳转到用户登录界面,如果完成登陆,则将进入规则链,为登陆用户提供权限之内的资源与操作。
Ⅲ Service
GeoServer对于权限粒度的控制达到了service级别,能够对用户的操作(OWS和REST)进行锁定和控制,在Geoserver中主要有两Services:OWS(WFS,WMS)和RESTful Service。
- OWS服务
路径:%GeoServerHome%/data/security/services.properties
e.g:wfs.Transaction = ROLE_WFS_WRITE
wfs.GetFeature = ROLE_WFS_READ
- REST服务
路径:%GeoServerHome%/data/security/rest.properties
e.g:<uriPattern>;[<method1>,<method2>…]=<role1>,<role2>
/**;GET,POST,PUT,DELETE=ROLE_ADMINISTRATOR
GET方法具有read-only属性,适合一般用户访问,而POST,PUT,DELETE等方法适合具有一定权限的角色使用。
通过各自路径下存储的properties文件,将资源、操作方法的操作权限分配给各个角色。
需要注意的是:在GeoServer的官方文档中提到,Service粒度的权限控制与Layer粒度的权限控制是无法配合使用的,即这两种控制是相对独立的,你无法指定特定图层中的特定OWS服务的请求和操作权限归属于某一个角色。
好了,以上便是关于GeoServer security模块的基本概念与实现原理,我将争取在这周内实现Spring Security与GeoServer Security的整合,在下一节中介绍如何在自己的Web应用中实现对调用GeoServer中发布的空间数据进行权限管理的内容。