我不会选择原始评论的措词方式,但它确实标识了潜在的合法问题。
具体而言,保证分离的关注点是身份验证与授权。
身份验证是指登录并获取身份的过程。系统就是这样来了解您的身份的,并用于诸如个性化,对象所有权等之类的事情。
授权是指您被允许做的事情,(通常)这不是由您是谁来决定的。取而代之的是,它由某些安全策略(例如角色或权限)确定,这些策略不关心您的姓名或电子邮件地址。
这两个可以彼此正交变化。例如,您可以通过添加OpenID / OpenAuth提供程序来更改身份验证模型。您可以通过添加新角色或从RBAC更改为ABAC来更改安全策略。
具有讽刺意味的是,如果所有这些都归为一类或抽象,那么作为降低风险的最重要工具之一的安全代码将变成高风险。
我曾在身份验证和授权过于紧密的系统上工作。在一个系统中,有两个并行的用户数据库,每个数据库都用于一种“角色”。设计它的人员或团队显然从未考虑过单个物理用户可能同时担任两个角色,或者可能有多个角色共有的某些操作,或者User ID冲突可能存在问题。这是一个公认的极端示例,但是使用它非常痛苦。
Microsoft和Sun / Oracle(Java)将身份验证和授权信息的集合称为“ 安全主体”。它不是完美的,但是效果很好。例如,在.NET中,您具有IPrincipal
,它封装了IIdentity
-前者是策略(授权)对象,而后者是身份(身份验证)。你可以合理质疑把一个决定内其他的,但重要的是,大多数的代码编写将是抽象的只有一个,这意味着它很容易测试和重构。
一个User.IsAdmin
字段没有什么问题... 除非也有一个User.Name
字段。这表明“用户”的概念定义不正确,可悲的是,这是在安全性方面有些耳熟能详的开发人员中的一个常见错误。通常,身份和策略应该共享的唯一内容是用户ID,而并非巧合的是,这正是Windows和* nix安全模型中如何实现的。
创建封装身份和策略的包装对象是完全可以接受的。例如,这将有助于创建仪表板屏幕,除了允许当前用户访问的各种小部件或链接之外,您还需要显示“ hello”消息。只要此包装器仅包装身份和策略信息,并且不声称拥有它即可。换句话说,只要它没有以合计root的形式出现。
由于YAGNI等原因,当您初次设计新应用程序时,简单化的安全模型似乎总是个好主意,但它几乎总是最终会在以后给您带来麻烦,因为令人惊讶的是,增加了新功能!
因此,如果您知道什么最适合您,则将身份验证和授权信息分开。即使现在的“授权”就像“ IsAdmin”标志一样简单,但是如果它与身份验证信息不在同一类或表中,那么您仍然会更好,以便在需要时以及何时需要使用安全策略更改后,您无需在已经运行良好的身份验证系统上进行重建手术。