我发现的大多数实现示例似乎都过于关注用户身份验证,而授权就是这样.例如,if语句检查用户的类型是否为admin.这对我来说似乎太过实施了.
在像我这样的实现中,无法知道用户在发起请求时所处的“页面”.因此,由PHP确定的仅为某些用户提供某些内容的方法对于我需要做的事情而言过于宽泛.
理想情况下,每个实体都有一种基于用户明确或用户所在的组或类型的访问控制列表.
我去了一家当地的书店,花了一个下午的时间浏览他们在PHP,MysqL和JavaScript上的所有内容.令人惊讶的是,大多数书籍几乎没有关于用户授权的任何内容.这吓坏了我!这必须由构建使用AJAX的大型Web应用程序的任何人解决,我似乎无法找到让我入门的东西.
我会感谢所有反馈,经验,技巧等(关于这个主题的任何书籍?)
首先,你熟悉unix file permissions吗?你在命令行的ls -l中看到的是-rwxr-xr-x. Unix选择了一种非常简化的ACL方法.每个登录的人都有一个用户ID(UID)和一个或多个组ID(GID)(whoami,组). Unix文件权限允许三个操作,Read,Write和Execute,它们可以打开或关闭.有2 ^^ 9个状态,这些权限很容易适合整数,然后Unix可以附加它
直接在文件系统中的文件整数.当用户尝试访问文件时,权限将从严格到允许进行比较,匹配允许的最宽松权限.因此,用户获得第一组权限,组获得第二组,任何人获得第三组权限.因此,可执行文件通常是755:只有所有者可以更改它,但任何人都可以阅读和使用它.
其次,LDAP是轻量级目录访问协议,旨在为多个网络用户提供对资源的访问. OpenLDAP是一种常见的Linux实现,而Windows Server上的Microsoft的Active Directory会说LDAP(有很多扩展). LDAP具有更强大的ACL系统.一般配置是通过[who] [授予的访问类型] [控制]访问[资源]或访问dn =“uid = matt,ou = Users,dc = example,dc = com”by * none以限制所有访问Matt的用户信息.对于更完整的讨论,我强烈推荐Mastering LDAP,特别是关于安全性的第4章. (这是我从我的直接知识中得到的一点.)我的印象是LDAP将这些信息存储在一个单独的数据库表中,但我不知道,也无法以这种或那种方式找到文档.我正在密切关注可能的架构.
简要总结一下:ACL采用用户令牌的概念,其中包含用户级别以上的可能组,以某种方式保护的对象集合,以及对这些部分的三个一致的可能操作 – 信息的3个维度. Unix存储其中两个维度,直接保护事物. OpenLDAP分别存储这三个维度,我们不太了解,但我怀疑是一个链接的树结构.
鉴于此,我们来看看如何为RESTful Web应用程序设计ACL系统.对于假设,我们会将您的应用程序分解为离散的可寻址单元 – 每个需要保护的东西都可以通过URI访问(http://example.com/users,http://example.com/page_pieces/ticker).我们的用户将是一个简单的UID / GID令牌 – 用户可以成为多个群组的一部分.最后,我们的可用操作将基于HTTP请求-GET,POST,PUT,DELETE等.我们现在需要一个能够有效处理三维数据数组的系统.我们的架构应该非常明显:( uri,userid,groupid,operations).我们故意将操作列反规范化为GET,…的字符串列表,所以我们只需要一个表.没有主键,因为我们永远不会真正通过ID查找.
查询将分两步完成:SELECT * FROM acl WHERE uri = @ uri,userid = @ userid将返回0或1行.如果它返回1行,我们就完成了并且可以grep permisssion以查看操作是否在列表中(使用*表示所有perms).如果我们得到0行,则运行第二个查询SELECT * FROM acl WHERE uri = @ uri,userid =’*’,groupid in(@groupid),它将再次返回0或某些行.如果它返回一些,循环并查看perms.如果它返回0,则执行最后一个查询SELECT * FROM acl WHERE uri = @ uri,groupid =’*’,它最终将返回0或1行.如果它返回1,请查看perms.如果返回0,则采取默认操作.
我们可以通过多种方式设置权限:
> INSERT INTO acl VALUES(@ uri,@ userid,”,’GET,POST’)允许单个用户GET或POST访问
>插入acl VALUES(@ uri,’*’,’admin,contributors’,DELETE’)
> INSERT INTO acl VALUES(@ uri,”)拒绝所有访问.
有几点需要注意:
>必须准确表达所有URI;这个解决方案无法设置更高级别的默认权限并让它们逐渐减少(作为对提问者的练习).> uri / uid / gid对的唯一性应该在某个时刻发生.应用程序可以处理它,或者在MysqL中,您可以执行ALTER TABLE acl ADD UNIQUE INDEX(uri,groupid)(查找其他DBMS中类似约束的文档).