《电子技术应用》
您所在的位置:首页 > 通信与网络 > 设计应用 > Spring Security的Web资源保护功能研究与扩展
Spring Security的Web资源保护功能研究与扩展
2015年微型机与应用第15期
赛序朋1,侯瑞春2,丁香乾2
(1.中国海洋大学 信息科学与工程学院,山东 青岛 266100; 2.中国海洋大学 信息工程中心,山东 青岛 266071)
摘要: 针对开源安全框架Spring Security的Web资源保护功能进行研究,分析框架的认证和授权两个主要过程,指出了框架对于用户和Web资源的授权信息外化存储这一关键企业级安全特性支持上的不足,进而对此进行了扩展。借助于Spring容器的依赖注入特性和安全框架的扩展性,结合数据库存储授权信息,本文设计了一个基于Spring Security的用户与Web资源授权信息动态存储方案,并给出了关键的程序代码。
Abstract:
Key words :

  摘  要: 针对开源安全框架Spring Security的Web资源保护功能进行研究,分析框架的认证和授权两个主要过程,指出了框架对于用户和Web资源的授权信息外化存储这一关键企业级安全特性支持上的不足,进而对此进行了扩展。借助于Spring容器的依赖注入特性和安全框架的扩展性,结合数据库存储授权信息,本文设计了一个基于Spring Security的用户与Web资源授权信息动态存储方案,并给出了关键的程序代码。

  关键词: 安全框架;访问控制用户认证;资源授权

0 引言

  权限管理是Web应用系统最重要的组成部分之一,担负着用户分级分类管理、系统和数据的访问控制等重要职责[1]。在B/S架构中主要体现在对系统的Web资源的保护。尽管Servlet规范定义了安全性接口,但因依赖应用服务器的具体实现,使用这种安全服务的应用可移植性较差。而且Servlet规范对于很多常用的企业级安全特性并未作出规定,使得多数应用服务器对这些特性不予支持。企业应用开发急需一种能够保障应用可移植性强、广泛支持企业级安全特性的安全解决方案。

  Spring Security[2]正是为解决上述难题而建立的开源安全框架。借助于过滤器技术和Spring框架,应用的可移植性得到了保证。这一框架还为应用提供了常用的企业级安全特性,比如用户切换、并发Session控制、领域对象的授权支持等[3]。尽管这是一个扩展性极好的安全框架,但是对授权信息的外化存储[3](将授权信息存储到数据库中或者磁盘文件等外部环境)这一关键企业级安全特性的支持很不完善。针对这一问题,本文通过研究框架的Web资源保护机制,通过自定义框架接口实现替代系统默认组件的方式,实现了一个动态权限设计方案。

1 Web资源保护机制

  Spring Security借助一系列Servlet过滤器为目标资源提供安全性增强[4],但并不需要在Web容器的配置文件中定义很多过滤器,而是借助于安全框架提供的代理过滤器将请求委托给IoC容器中配置的安全过滤器链来处理,使得过滤器链中的过滤器可以享受到依赖注入[5]服务,而且减少了框架与Web环境的耦合性。

  Web资源[6]是指能够通过URL访问到的一切资源。对Web资源的保护是基于Web的企业级应用最主要的安全需求。Spring Security框架通过过滤器技术对Web资源进行保护,包括认证和授权两个主要过程。

  认证[7]是验证一个用户与其声明身份是否相符的过程,用户必须提供凭证,通常是密码。用户在访问目标资源前,框架必须拦截到请求,作出认证处理。比如收集用户凭证、确认用户身份。在完成认证后,框架必须管理好认证结果,以供用户后续访问使用,避免重复认证。如果通过认证,则生成封装该用户授权信息的Authentication认证对象供授权使用。如果未通过认证,则返回登录页面。

  授权[7]是控制对受保护资源的访问的过程,必须在认证之后进行。当已认证用户访问受保护资源时,授权过程根据用户的认证对象和受保护资源的访问属性判断是否允许用户访问这个资源。如果授权被通过,则执行目标资源;否则执行拒绝访问页面。如果未认证用户通过直接输入URL访问受保护的资源,则会重定向到登录页面。

2 认证与授权分析

  2.1 认证过程分析

  当用户在登录页面提交包含用户名和密码的请求时,认证过滤器[8]会截获并处理这个请求,认证过程开始:

  (1)认证过滤器从请求中获取用户名和密码封装成认证对象[9],然后将其交给配置的认证管理器来完成认证工作。如果完成认证,则返回到认证过滤器中,接着执行安全过滤器链的下一步。

  (2)认证管理器通过认证提供器完成具体的认证操作。认证提供器提供保存在服务器端的用户信息。认证管理器持有一组认证提供器,按顺序遍历配置的认证提供器。如果某个认证提供器成功认证,则认证结果封装到认证对象中,供授权使用。其他认证提供器便没有机会再去完成本次认证请求。

  (3)认证提供器处理用户认证请求的基本过程包括:从缓存或数据库中获取用户信息对象,判断用户状态(是否锁定、是否有效、帐号是否过期),启动用户输入信息与服务器端存储的用户信息的对比。如果对比操作正常完成,则表示通过认证,返回认证管理器,再返回认证过滤器。如果对比操作抛出异常,则表明认证失败,这一异常将上抛至认证过滤器处理,处理的结果是转到认证失败页面。

  通过认证提供器,应用与认证信息解耦,一切差异都只存在于框架配置文件的元数据中,甚至可以把认证信息转移到数据库或者目录服务器中实现动态存储,这样认证信息的修改就无需重启应用了,这正是企业级应用的安全需求。

  2.2 授权过程分析

  当用户请求受保护资源时,授权过滤器要判断是否允许用户访问受保护资源。整个授权过程分为如下步骤:(1)授权过滤器拦截请求,经过预处理后,如果满足条件,则进入“事前评估”过程,即访问资源前的安全检查。(2)如果完成“事前评估”,则表示可以访问目标资源,接着执行安全过滤器链的下一步。(3)如果“事前评估”过程发生异常,则表示不能访问目标资源。此时安全过滤器链中异常转换过滤器将捕获并处理异常,或者转向访问拒绝页面(用户权限不足),或者转向登录页面(用户未认证)。

  “事前评估”是授权过程的关键,其操作封装在授权过滤器父类的beforeInvocation方法中,步骤总结如下:

  (1)获取目标资源的授权信息。如果目标资源受到保护,则返回封装了目标资源和授权信息的ConfigAttributeDefinition对象。如果目标资源不受保护,则返回null,退出“事前评估”。

  (2)获得当前用户的认证对象。如果认证对象处于未认证状态,则认证管理器介入,启动认证流程。若在认证过程中产生异常,则返回登录页面给用户。如果认证对象处于已认证状态,则进入授权阶段。

  (3)进入授权阶段,授权管理器通过引用的几个授权投票器实施具体授权操作。

  (4)如果授权成功,则进入安全过滤器链的下一步骤,通常是调用目标资源。如果授权失败,则抛出授权异常,被异常转换过滤器捕捉处理,返回给用户访问拒绝页面。

  授权过滤器通过ObjectDefinitionSource接口获取配置文件中的资源授权信息。企业级应用通常将资源授权信息存储到RDBMS或者目录服务器中,实现动态调整应用的资源授权信息的目的。Spring Security没有对这一企业特性给出直接支持,但框架是基于IoC容器组织各种组件,因此可以自定义资源授权接口的实现类并进行扩展。

3 动态存储授权信息研究

  3.1 默认的授权信息存储方式

  Spring Security默认存储授权信息的方式是直接写在配置文件中。这种做法仅仅适合演示或者小型应用,会带来以下几个问题:首先,配置文件代码急剧膨胀,难以维护。其次,无法实现授权信息的动态存储。因为配置文件只在应用启动时被加载到内存中,每次修改配置文件都需要重新加载应用才能生效。企业级应用都要求能够动态授权信息。通常做法是把授权信息存储在数据库、目录服务器或者磁盘文件上,使用程序进行增删改查操作。但框架对授权信息的外化存储支持并不完善,需要自行扩展。

  3.2 动态存储授权信息方式的配置

  对于用户授权信息的外化存储,框架给出了较好的支持,通过配置<jdbc-user-service>元素,指定自定义数据表以及提取用户授权信息的SQL语句,这里不再详细讨论。对于资源授权信息的外化存储,框架没有提供支持方法,也没有留下扩展接口。不过,框架提供了调整安全过滤器链的功能,以及基于IoC容器管理组件的方式,从而能够用自定义组件替换默认实现,进行功能扩展。首先,自定义用户表、资源表、角色表以及相关映射表,如图1所示。其次,配置资源授权接口的自定义实现类,同时为其提供定制的提取资源授权信息的SQL语句。再次,配置授权过滤器Bean,将资源授权接口的自定义实现类配置到授权过滤器的objectDefinitionSource属性中,并利用框架提供的调整过滤器链功能标签    <custom-filter>将配置的授权过滤器Bean放到安全过滤器链的默认授权过滤器之前,使得默认授权过滤器不再执行授权操作。

001.jpg001.jpg

  3.3 资源授权接口实现

  当Web容器装载应用时,spring会自动解析配置文件中的资源授权信息,按特定格式生成默认的资源授权实现类。对于采用数据库存储资源授权信息的应用,必须自行将资源授权信息从数据库中取出并按照特定格式存储到资源授权接口实现对象中,并将此对象设置到授权过滤器的属性中。通过实现FactoryBean接口并且继承JdbcDaoSupport的自定义类来提供资源授权对象。其中关键是buildRequestMap()方法调用findResources()方法从数据库中获取资源授权信息,组装成特定格式,实现代码如图2和图3所示。其中findResources()方法通过内部类ResourceMapping的execute()方法利用spring JDBC技术完成数据存取操作。

4 结束语

  Spring Security安全框架通过过滤器技术,为应用提供了强大的Web资源保护机制,安全命名空间更是进一步简化了配置代码,但默认组件并不支持授权信息的外化存储。本文对框架的认证与授权流程及原理进行了研究,在此基础上对用户授权信息和资源授权信息的外化存储进行了设计,这种方案符合企业级应用对于授权信息的动态存储,对于应用的权限设计方案具有一定的参考价值和实用性。

参考文献

  [1] 信科,杨峰,杨光旭,等.基于RBAC权限管理系统的优化设计与实现[J].计算机技术与发展,2011(7):172-174,249.

  [2] CRAIG W.Spring实战[M].耿渊,译.北京:人民邮电出版社,2011.

  [3] 罗时飞.敏捷Acegi、CAS[M].北京:电子工业出版社,2005.

  [4] MAK G, LONG J, RUBIO D. Spring攻略[M].陈宗恒,姚军,蒋亮,译.北京:人民邮电出版社,2011.

  [5] 罗时飞.精通Spring—深入JavaEE开发核心技术[M].北京:电子工业出版社,2008.

  [6] 周秀,刘培顺,刘加标,等.海洋环境云平台访问控制系统研究[J].微型机与应用,2015,34(7):9-12,23.

  [7] 路鹏,殷兆麟.基于Spring的Acegi安全框架认证与授权的分析及扩展[J].计算机工程与设计,2007(6):1313-1316.

  [8] 许军林,蒋年德.Acegi安全框架在Web系统中的应用[J].现代计算机(专业版),2007(9):25-26,57.

  [9] 黎小红.基于Spring框架应用的权限控制系统的研究和实现[J].计算机与信息技术,2006(11):4-7.


此内容为AET网站原创,未经授权禁止转载。