当谈到程序权限管理时,人们常常会想到角色的概念。 角色是代表一系列可执行操作或职责的实体,用于限制您在软件系统中可以做什么和不能做什么。 用户帐户通常与角色相关联,因此用户在软件系统中可以执行的操作取决于与其关联的角色。
例如,如果用户使用与“管理员”角色关联的帐户登录系统,则该用户可以执行项目管理员可以执行的所有操作。 无论管理员能做什么,整个用户都可以获得所有权限。
基于角色的访问控制
由于角色代表可以执行的操作的概念,因此合理的方法是在软件开发中使用角色来控制对软件功能和数据的访问。 你可能已经猜到了,这种权限控制方法称为基于角色的访问控制,简称RBAC。
实际中使用的RBAC访问控制有两种方法:隐式(模糊)方法和显式(显式)方法。
如今,仍然有大量的软件应用程序使用隐式访问控制。
隐式角色:
即直接通过应用中的角色验证用户是否具有操作权限,例如CTO、技术总监、开发人员等。
开发工程师可以使用打印机。 假设有一天开发工程师不被允许使用打印机。 这时需要从应用程序中删除相应的代码。 再比如,在应用中,CTO和技术总监可以查看用户、查看权限。 突然有一天,技术总监不允许查看Users,需要从相关代码中的判断逻辑中删除查看权限; 即粒度以角色为单位进行访问控制,粒度比较粗。 如果进行修改,可能会发生多次代码修改。
以“项目管理员”为例。 系统并没有明确定义“项目管理员”可以执行哪些操作。 它只是一个字符串名词。 开发人员通常会将此术语写入程序中以进行访问控制。 例如,要确定用户是否可以查看项目报告,程序员可能会编写如下代码:
隐式地基于角色的权限控制:
if (user.hasRole("Project Manager") ) {
//show the project report button
} else {
//don't show the button
}
在上例中,开发人员通过判断用户是否具有“项目管理员”角色来决定是否显示“查看项目报告”按钮。 请注意,上面的代码没有明确定义“项目管理员”角色中包含哪些可执行操作。 它只是假设与项目管理员角色关联的用户可以查看项目报告,并且开发人员也可以查看项目报告。 根据这个假设编写 if/else 语句。
脆弱的权限策略
上面的权限访问控制是非常脆弱的rbac角色权限表设计,并且不可扩展,相当于是硬编码的。 。 。 。 权限要求的一个很小的变化都可能导致上面的代码需要修改。 如果我说我们需要“部门管理员”角色游戏角色,他们还可以查看项目报告。 需要再次修改代码吗? 真是麻烦啊!什么东西都比比皆是,如何才能改变现状呢?
修改过的隐式的基于角色的权限控制:
if (user.hasRole("Project Manager") || user.hasRole("Department Manager") ) {
//show the project report button
} else {
//don't show the button
}
如果需求方需要动态创建和删除角色,以便配置自己的角色,该怎么办?
正如上述情况,这种隐式(静态字符串)形式的基于角色的访问控制很难满足需求。 理想情况下,如果权限要求发生变化,则不需要修改任何代码。 如何才能实现这一目标?
显式访问控制:好的就是更具可扩展性
从上面的例子我们看到,当权限需求发生变化时,隐式的权限访问控制方式会给程序开发带来沉重的负担。 当权限需求发生变化时,无需修改代码即可动态满足需求。 我们的理解是,即使在正在运行的系统上,您也可以修改权限策略而不影响最终用户。 当你发现一些错误或者危险的安全策略时,你可以快速修改策略配置,而你的系统仍然可以正常使用,而不需要重构代码和重新部署系统。总结就是不需要修改代码或停止服务器。
怎样才能达到上述理想的效果呢?
想一想上面例子中的代码最终的目的,最终实现什么样的控制?
从根本上讲,这些代码最终保护资源(项目报告)并定义用户可以对这些资源执行哪些操作(查看/修改)。 当我们把权限访问控制分解到这个最原始的层面时。
在程序中,谁可以访问某个资源是通过权限来控制的,角色聚合了一组权限。 这样,如果某个角色无法访问某个资源,只需要将其从该角色所代表的权限集中移除即可; 无需修改多个代码; 即粒度是基于资源/实例的; 粒度更细。 角色对应于资源访问。 下面只要定义明确的资源,那就是资源操作的集合。 只要将资源交给某个角色,那么这个角色就有访问权限。
我们可以修改上面的代码块,以更有效地基于资源语义进行权限访问控制:
if (user.isPermitted("projectReport:view:12345")) {
//show the project report button
} else {
//don't show the button
}
在上面的例子中,我们可以清楚地看到我们在控制什么。 上面的语句明确指出“如果允许当前用户查看编号为12345的项目报告,则显示项目报告按钮”。 查看12345的整个项目报告作为资源。 您需要分配特定角色并配置特定用户。 这里的资源是最小粒度的,无法进一步划分。 如果想要定义更细粒度的代码,就需要修改代码。 这种动态修改是不可能的。 这是笔者的理解。 你还可以拥有搜索、删除等各种权限,详细来说这些都是CRUD权限。
RBAC新解读:基于资源的访问控制
这种显式的机制给我们带来了灵活的权限模型。
如果您仍想保留或模拟传统的基于角色的权限访问控制,您可以直接向角色分配权限(可执行操作)。 在这种情况下,您仍然使用基于角色的权限访问控制(不同之处在于您需要显式定义角色中的权限,而不是使用传统的角色字符串来隐式控制权限)。
但在这种新模式下,你不必再局限于角色。 您可以根据需要直接向用户、组或其他对象分配权限。 由于上述显式的、基于资源的权限访问控制的诸多好处,或许可以给RBAC一个新的定义:“基于资源的访问控制”。
阿帕奇·希罗
如果您好奇是否有一个现实世界中多个系统使用的基于资源的权限控制框架,Apache Shiro。 它是 Java 平台的现代权限管理框架。 通过其权限理念,Shiro很好地支持了基于资源的权限访问控制。 这也是笔者学习Shiro的意义所在!
其实笔者之前就了解过基于角色的权限访问控制,而且还是比较不错的。 只是作者误会了,理解为这类资源。 角色可以随意创建橙光游戏,细节是硬编码的。 ,即资源可以分配给角色。 其实这就是基于资源的权限访问控制。
笔者上次在杭州一家公司面试时,被一位比我年轻的面试官问了一个问题。 如何控制权限。 笔者并没有专门研究过这个东西。 我只知道它比较复杂。 我只知道它比较复杂。 用户赋予角色,角色被分配一定的资源。 这些资源就是这样定义的rbac角色权限表设计,比如CRUD等,界面上显示的按钮等信息都是资源。 我猜对了,哈哈。 小面试官说我今天说的勉强正确。 其实我也不是很清楚怎么实现,所以才来了解Shiro。 除此之外,我还想了解一下大师写的代码的整体设计结构。 可扩展性,设计模式可以导出,非常巧妙,易于扩展。 这样的学习值得我们作为刚毕业的初级程序员,也更有利于我们整体的提升。 笔者之前也去看过设计,还是觉得对图案子类书籍的理解不够深入,比较浅。 在实际项目中,这样的设计更容易理解。 但你想一想,如果你来写,会是什么样子呢?
文章来源:https://blog.csdn.net/u012881904/article/details/53749239