基于Spring Security的web应用安全控制研究与实现摘要:针对web应用安全控制问题,提出了一种基于spring security开源的安全框架的解决方案,分别从web应用中的用户认证和授权两个方面实现对web应用安全的控制,从而提高web应用的安全性。
关键词:web应用 spring security 安全访问控制0 引言web应用作为一种开放式的服务平台,其无时无刻不在面临非法访问者的访问或者攻击,同时也面临内部用户的非法操作,使得存储在web应用中的数据时刻可能被窃取和破坏的危险。
这就需要我们提供一定的安全控制规则来确保web应用的安全。
然而在系统实施web应用安全控制的时候,主要有:基于web容器的安全认证。
基于第三方插件的安全认证。
独立开发的安全认证。
对于第一种方式,它是传统的安全认证方式,对具体的web服务器依赖强,移植代价高。
对于第二种方式,不依赖具体的web服务器,灵活性强,但受自身功能限制,因此,插件选取很关键。
对于第三种方式,其将代码耦合到相应的业务逻辑中,增加维护的难度,降低了开发效率,不便调试。
从灵活性、易用性、功能和投入等方面考虑,第二种方式是一种比较理想的方式。
如在j2ee平台比较流行的开源框架spring security,其提供了描述性安全访问控制解决方案。
本文通过对spring security安全框架的工作原理进行简单的剖析并展示如何将spring security安全框架应用到我们具体的web应用中。
1 spring security简介如引言所阐述的,web应用的安全控制主要包括外部和内部两个方面。
在安全控制的时候需要从以下几个方面考虑:能够认证合法的用户、能够对web 请求进行安全保护、能够对业务层面的方法进行安全保护、能够做到对实体级别的保护等四个方面,而这四方面概括起来则分为两部分用户认证和用户授权。
用户认证是指证某个用户是否为系统中的合法主体,即用户是否能够访问该web应用,用户认证一般通过验证用户名和密码来完成认证。
用户授权指的是验证用户在访问过程中是否有权限执行某个操作。
spring是一款轻量级的开源框架,采用java语言实现的[1]。
spring security是基于spring的安全框架,其充分运用了spring 中的依赖注入(di,dependency injection)和面向切面(aop ,aspect oriented programming)技术,使得开发者可以通过xml配置文件以无侵入式的方式快速的将其部署到已有或者新的web应用中。
它提供了认证、授权、访问控制、会话管理等多种功能,用于加强任何java应用的安全,但最常用于基于web的应用。
在web 安全控制的两个部分,spring security分别提供了多种实现方式。
在用户认证部分,spring security提供了包括http基本认证、http 表单认证、http摘要认证、openid和ldap等主流的认证方式。
在用户授权部分,spring security提供了基于角色的访问控制和访问控制列表(access control list,acl),可以实现领域对象的细粒度控制[2]。
1.1 spring security原理spring security 框架的主要组成部分是:安全代理、认证管理、访问决策管理、运行身份管理和调用后管理等[3]。
其对访问对象的整体控制流程框架如图1所示:图1 spring security访问控制流程框架(1)安全代理安全代理的主要作用是拦截所用用户的请求,并协调其他安全管理器实现安全控制。
它的配置方式是在web.xml中配置delegatingfilterproxy实例,delegatingfilterproxy负责的是将http请求委派给实现java.util.logging.filter接口的spring bean。
(2)认证管理确定用户的身份和凭证。
其配置是在spring security提供的xml 标签中配置,为认证配置相应的认证方式,同时在配置中为认证方式配置认证的凭证。
(3)访问控制决策管理关于是否允许用户访问应用中的一个资源做决策。
它的工作原理是通过访问控制决策管理器中的投票者对访问控制决策投票,投票者可以投票赞成授权、弃权或者拒绝访问资源。
(4)运行时身份管理确人当前的主体和凭证的授权在保护资源的权限变化适应。
(5)调用后管理确认主体和凭证的权限是否被允许查看保护的资源返回的数据。
2 spring security在应用中的部署和环境的设置如spring security的简介所述,spring security是基于spring 的安全框架,所以在部署spring security之前一定要确保spring 框架环境已经设置好以及spring security的jar已经部署到lib 中。
2.1 在web.xml中配置安全代理:springsecurityfilterchainorg.springframework.web.filter.delegatingfilterproxyspringsecurityfilterchain/*同时为spring security安全控制指定其配置文件,虽然我们可以将web和服务层配置以及安全配置文件配置到同一个配置文件中,但是将安全配置分离到一个单独的文件(如spring-security.xml)做法更好,易于维护[2]。
在web.xml中指定安全配置文件位置,让contextloaderlister在启动时加载该文件。
.../web-inf/spring-security.xml2.2 认证管理的配置2.2.1http安全配置这里我们为认证管理配置了基于表单的认证方式,其中login-page、defaulet-target-url和authentication-failure-url这三个属性分别指定了默认的登入界面、登陆成功跳转的页面和登陆失败后跳转的页面,其中login.jsp必须使用spring security专有的表单操作url和输入字段名称,当然也可以不用配置这三个属性,因为spring security 已经默认为我们提供了,这也就是为什么login.jsp中必须包含spring security专有的表单操作url和输入字段名称。
这里我们也可以配置其他的认证方式如http基本验证,其和表单认证同时启用时会采用后者。
atuo-config=“true”表示自动配置典型的web应用安全需要的基本安全服务,如intercept-url,将访问属性与用户的权限比较,确定用户可以访问相应的url。
2.2.2验证器配置:默认情况下,spring security是采用如下sql语句查询用户细节和权限:select username,password,enabled from users where username=?select username,authority from authorities where username=?为了让spring security用这些语句查询用户细节,我们必须在数据库中创建对应的表。
但往往当我们把spring security部署到我们的web应用中,用户细节信息已经存在数据库了,此时通过自定义的sql语句查询遗留数据库中的用户细节:同时我们也可以在认证管理器中为数据库配置相应的加密算法,目前应用最广的加密算法的是md5加密。
2.3 访问控制决策管理配置在spring security中,其默认为提供三种基于投票的访问决策管理器,分别为affirmativebased:至少一个投票者投票赞成授予权限、consensusbased:投票者一致赞成授予权限和unanimousbased:所有投票者赞成或者弃权(没有拒绝访问的投票者)。
默认情况下,如果我们没有指定访问决策管理器,则spring security自动配置一个affirmativebased访问控制管理器,其包含了两个投票者:rolevoter和authenticatedvoter。
其中rolevoter根据用户角色对访问控制决策投票,其只处理以role_前缀开始的访问属性,当然我们也可以定制的。
authenticatedvoter则是根据用户验证级别对控制决策投票。
但是有时这个访问决策管理器并不能满足我们的需求,此时我们可以自己创建相应的管理器,往往多数情况下,我们只需要自定义一个投票者,投票者需要实现accessdecisionvoter接口即可,并在投票者中指定只对如ip_前缀开始的访问属性投票,然后将投票者部署到访问决策管理器中。
如最后把这个访问决策管理器指定给配置元素。
以上的配置都只是加强了url的访问控制,有时我们需要更深层次的访问控制。
例如,对方法上的细粒度安全控制或者对领域对象的安全控制。
在spring security 其通过spring aop引入切入点和切面逻辑为方法调用的拦截提供了支持。
其对方法保护配置如下:其中accessdecisionmanager是自定义的访问控制决策器,并定义了具有角色role_user,role_guest用户才可以调用服务层的list等方法。
在对领域对象的安全控制时,spring security 提供了对访问控制列表的支持,可以很方便地对不同的领域对象的不同角色设置不同的访问属性[4]。
访问控制列表的实现中有3 个重要的概念,对应于4张数据库表。
(1)授权的主体:即系统中的用户,通过用户实体对象来分配系统功能的授权,它是由acl_sid 实体对象来表示的。
(2)领域对象:表示需要进行访问控制的实体对象,可以说需要权限控制的功能实现对象需要在这里进行注册,它由acl_class 和acl_object_identity 两个对象来表示,前者保存实体实现时所对应的java类名,后者保存的是实体对象本身。
(3)访问权限:表示一个用户对一个系统功能对象所具有的操作权限。
由acl_entry 对象来表示,acl中预定义了5种基本权限的常量:read(读)、write(写)、create(写)、delete(删除)和administration(管理)。
访问控制列表服务的配置://数据源指定//数据库的查找策略//acl缓存//功能实现类标识查询//功能权限标识查询访问控制列表的实现:acl 提供了注解的支持,只须通过注解注入校验方法,就可以在功能执行前进行权限校验。
如://标示方法的操作权限是admin 级别,只有admin 角色的用户才能操作当前方法@ preauthorize(“hasrole(‘role_admin’) or haspermission( id,com.ewcmscore.site.model.file,’admin’)”)3 结束语本文通过示例代码展示了将spring security部署到我们的web 应用中,spring security安全框架通过xml文件配置为web应用提供了强大的安全保护,其不仅可以实现url的访问控制,而且还可以实现类方法级别和领域对象级别上的安全保护,对web应用的安全控制实施有一定的参考价值。