本文讨论了如何使用角色的概念来管理安全策略,以及基于角色的安全应用程序安全机制在很大程度上是不够的。我讨论了我认为是保护应用程序更好的方法。编程
当谈到应用程序安全性时,大多数人都对现有的角色概念感到满意。角色是一般表明一组行为或责任的命名实体。这些行为转化为你能够或不能够用软件应用程序作的事情。 角色一般分配给用户账户,所以经过关联,用户能够“完成”归因于各类角色的事情。安全
例如,若是用户登陆到应用程序,而且他们的账户被分配了“项目经理”角色,那么咱们就开始臆测该用户能够“作”项目经理在应用程序中可以作的全部事情——在项目中添加或删除员工,生成项目报告等。bash
在这个意义上,角色主要是一个行为概念:角色给你一个用户能够在应用程序中作什么的概念。工具
一个角色主要是一个行为概念,开发软件的逻辑步骤是使用角色做为控制访问应用程序功能或数据的手段。 正如您所预料的那样,大多数人称之为基于角色的访问控制(简称“RBAC”)。 可是,实际实现和执行访问控制主要有两种方式:一种是隐式的,另外一种是显式的。 目前绝大多数的软件应用程序都使用隐式访问控制。 我认为显式访问控制对于保护当今的软件应用程序来讲更好。测试
Implicit Access Control 如前所述,角色表明行为或责任。可是,咱们如何确切地知道什么样的行为或责任与角色相关?spa
答案是,对于绝大多数的应用程序,你不知道这个角色表明什么。您固然有一个好主意 - 您知道具备“管理员”角色的人可能会锁定用户账户或配置应用程序的某些部分,也多是分配了“客户”角色的用户账户能够将商品放入购物车或请求新产品。但一般没有什么具体定义这些行为是什么。设计
以字符串“Project Manager”为例。 这只是一个字符串名称——除此以外,软件程序能够查看“基于这个名称,我知道用户分配这个角色能够作X,Y和Z”。 开发人员一般使用这个名字来编写应用程序。 例如,要查看用户是否被容许查看项目报告,一般会看到以下所示的代码:code
//Listing 1. Example Implicit Role-Based Access Control security check:
if (user.hasRole("Project Manager") ) {
//show the project report button
} else {
//don't show the button } 复制代码
在此示例代码块中,软件开发人员根据“项目经理”角色(多是项目要求)作出是否显示按钮的决定。可是请注意,上面的代码中没有任何明确的说“项目经理角色被容许查看项目报告”。没有人在软件中的任何地方定义行为陈述——这意味着“项目经理”用户能够查看项目报告,所以开发人员编写反映该假设的if/else语句。对象
像上面的例子那样的安全访问控制很是脆弱。也就是说,即便安全要求发生轻微变化,也极可能会破坏,失败或致使效率低下。 举例来讲,让咱们假设编写软件的团队被告知:“顺便说一下,咱们须要一个新的 部门经理 角色,他们也须要可以查看项目报告。实现它”。 如今软件开发人员须要回到代码中来改变它是这样的:ci
//Listing 2. Example Modified Implicit Role-Based Access Control security check:
if (user.hasRole("Project Manager") || user.hasRole("Department Manager") ) {
//show the project report button
} else {
//don't show the button } 复制代码
而后,开发人员须要更新测试用例,从新构建软件,检查存在的任何质量保证流程,以及安排从新部署到生产环境——全部这些都是因为新的安全要求。 可是,若是管理层回来并要求另外一个角色可以查看报告,会发生什么?或者若是他们之后须要移除那个能力呢? 或者,若是软件须要支持在运行时动态建立或删除角色的功能,那么他们但愿客户可以本身配置角色呢? 在任何这些状况下,常见的隐式(静态字符串)基于角色的访问控制方法都没法知足安全需求。做为一个理想的安全策略,在发生变化时是无需作出源码级别的调整的。
正如咱们上面看到的,用隐式访问控制方法改变安全策略可能会对软件开发产生影响。若是安全策略更改没有强制代码重构,那将会好不少。理想状况下,若是安全策略能够在应用程序运行时进行更改,那么最好不要影响最终用户。这对于安全来讲甚至更好,由于若是您发现错误或危险(或者您犯了策略错误),则能够将策略快速更改成正确的配置,而且软件仍然能够正常运行。
从根本上说,这些检查试图保护资源(项目报告)以及用户能够对这些资源作什么操做(例如查看/阅读这些资源)。当你把它分解到这个最原始的层次时,你就能够开始用更细粒度(和变化弹性)的方式来描述安全策略了。
//Listing 3. Example Explicit Access Control security check:
if (user.isPermitted("projectReport:view:12345")) {
//show the project report button
} else {
//don't show the button } 复制代码
这个例子更明确的是什么访问被控制。冒号分隔的语法在这里并不重要——这仅仅是一个例子。更重要的是,咱们基本上是检查“若是当前用户能够查看ID为”12345“的”projectReport“,则显示”项目报告按钮“。也就是说,咱们用一个用户账户明确地概括了关于特定资源实例的具体行为陈述。
减小代码重构:经过基于应用程序能作什么的代码,咱们将安全性基于应用程序自己核心的东西,以及应用程序与之交互的资源变化要少得多。使用这种方法,软件开发人员能够修改安全检查,由于他们在应用程序的功能上工做 - 而不是像隐式RBAC常常须要的那样。
资源和行动是直观的:表明什么被保护,以及如何采起行动是一个更天然的思考问题的方式。面向对象的编程范例和REST通讯模型从根本上反映了这个观点,并所以而很是成功。
灵活的安全模型:上面的代码示例并不指定如何容许用户,组或角色对资源执行操做。这意味着能够支持任何安全模型设计。例如,也许行为(权限)能够直接分配给用户。或者也许他们能够被分配给一个角色,而角色又被分配给一个用户。也许有团体的概念,与角色等有联系。可能性是开放的,能够根据您的应用程序进行定制。
外部化安全策略管理:因为源代码只反映资源和行为,而不反映用户,组和角色的组合,因此这种关联管理能够外部化到代码的不一样部分或专用工具或管理控制台。这意味着开发人员不须要花时间进行安全策略更改,相反,业务分析师甚至最终用户能够根据须要更改安全策略。
欢迎关注:www.renrunyun.com