建立一个安全库,我想我正在过度建设它

Kei*_*thS 8 .net c# architecture security

所以我正在构建一个自定义安全库,它与我们的数据库连接.它应该为内部应用程序提供基本的访问控制:某些用户可以执行X,而其他用户则无法执行.我目前的需求非常基本,但是这个库最终会被多个应用程序使用并控制很多安全性.

我的基本对象模型是User是零个或多个Groups的成员.这些组授予零个或多个权限.实际上,这些都是一对多的,但我不想参考这一点.权限仅限授权(如果没有组授予您权限,您没有权限,但没有"拒绝"覆盖授予的权限,例如在Windows RBS中),并且组可以嵌套(第2层用户)拥有第1层的权利,加上一些新的权利.当试图访问程序的安全区域时,应用程序将通过检查其组层次结构强制断言用户具有必要的权限.

但是,我希望库中内置多个级别的冗余.特别重要的是,无权更改安全设置的用户不应该这样做.因此,我想在大多数情况下使这个安全层次结构只读,因此无法在内存中添加必需但拒绝的权限.只有当用户已经证明他们有权通过向只读用户提供该权限来修改安全设置时,属性是否可以从代码级别进行设置.

这就是我认为我已经过度建造它的地方.为了做到这一点,该领域已经形成了分裂的个性; 每个对象的两个副本,一个只读,另一个不.readonly版本是默认生成的版本; 任何产生可写版本的操作都要求当前登录的用户具有进行安全性更改的权限.这导致两个用户(用户和可配置用户),两个组,两个权限,每个有两个接口(可配置派生自readonly)...你明白了.

我已经意识到,基本上所有这些额外的人都会停下来的是其他开发人员,他们通常都值得信赖(这是一个内部应用程序,我们控制着这个应用程序使用的所有资源,开发人员通常获得管理员权限很多).如果我可以相信触摸代码的人知道他们正在做什么,那么应用程序可以是可读写的,并且通过聪明的代码片段可以"提升"权限的可能性也不会有问题.

帮助我理智.我应该遵循不同的模式吗?我不相信其他开发者吗?我不想与Windows安全性集成,但已讨论过该选项; 主要缺点是访问权限将在整个公司的Active Directory中维护,并且此应用程序的用户管理员不应具有对整个系统安全性的那种访问权限.

编辑:一些好的评论和答案.AD或其他集成安全性并非完全脱离桌面,但我们在开始开发之前就讨论过它,并发现了一些缺点.所以,这里有一些我/我们的想法,为什么我们决定采用"自定义"安全设置:

  • 该应用程序的使用完全在内部.因此,这个应用程序的安全性并不是防止外部攻击/恶意收购,而是让乔办公室工作人员不要根据业务政策做一些他不应该做的事情.如果Joe最终奇迹般地找到了在应用程序中使自己成为"上帝"的方法,他的能力仍然非常有限,因为应用程序本身对数据库和其他资源的访问非常有限,其中大部分都是他需要做的无论如何,工作因为甚至是最低级别的用户而被授予.

  • 尽管如此,如果用户的Windows密码遭到网络钓鱼,破解或键盘攻击,如果应用程序使用集成安全性而不是传统登录,攻击者可以通过应用程序"免费"获得对客户端数据的一些认真访问权限.应用程序的单独安全层至少提供冗余的可能性; 他们必须破解两套凭证而不是一套,而第二套凭证被锁定在破解用户无法自由访问的另一层数据库安全性之后.

  • 从开发/管理角度来看,使用Active Directory或其他集成安全性存在一些问题.

    1. 首先,该部门的成员"交换办公桌",并在彼此的计算机上做相当多的事情.与Windows安全性集成需要用户一直记录操作系统以更改应用程序当前登录的用户,而不是仅以其他用户关闭,重新打开和登录应用程序.
    2. 其次,将使用该软件的部门经理是在应用程序中处理安全权限的合理人选,但不是向其提供AD管理员访问权限的合理人选.平衡需要AD中的额外一层角色来提供可以访问AD的"子管理员",但仅授予某些人某些权限.还有文件要求将安全管理集成到应用程序中,IMO使AD集成不可行.
    3. 最后,据我所知,Windows Integrated Security没有"权限"层.您声明用户处于特定角色,而不是断言用户具有执行某项操作的声明权限,而该推断是该角色有权继续.因此,我可以开发一个系统,要求AD为应用程序中的每个特定安全设备发挥作用,嵌入到用户将拥有的逻辑角色中(行政噩梦,我确信网络管理员会为防止他的安全而战斗(或)我们定义了属于已知角色的大量功能,嵌套角色以创建"用户级别",如果用户需要访问下一级别的一个功能,他们必须得到整个级别(或AD和我的应用程序必须更改以将该功能分成特定的可分配角色).

考虑到所有这些,简单的解决方案是在应用程序的范围内包含安全性,而不是绑定到网络安全性.我们得到了一个安全结构,我们可以相对轻松地维护,在应用程序停止.

编辑2:作为这个问题的结尾,我最终得出的解决方案是保留我的可变对象层次结构,然后创建一个简单的接口,IAuthUser,用户的基本信息和权限的只读成员.IAuthUsers仅在一个位置创建 - 在登录期间 - 通过将使用凭据检索的用户复制到实现公共接口的私有类中.它们用于所有身份验证和授权,方法是在启动时查询从用户的组成员身份投影的所包含权限列表.它们永远不会变回可变用户,因此永远不会保存回数据库.同时,可变用户不能在登录过程之外转换为IAuthUsers,因此对授权无用,并且如果没有提供有权在对象中检测到更改类型的IAuthUser,则无法将它们保存回数据库(通过将其与DB中当前的版本进行比较)

Jef*_*ard 2

我不会拥有分割层次结构,而是拥有“用户可以修改安全设置”权限,并在用户尝试编辑某些内容时断言。