6

我有一个需要身份验证的区域的站点。现在,我在该区域的所有控制器上使用角色属性,并运行查询以检索该用户 ID 及其所有设置。

每次加载该区域的控制器时,我都在检索用户 ID 和设置,这对我来说似乎是一种代码或设计气味?我不确定我是否应该使用会话,或者 ASP.Net MVC 2.0 是否提供了一些独特的方法来处理这个问题。另一个问题是安全性。

总的来说,我真的不知道该转向哪个方向。设计方面,我希望用户登录到该区域时只检索一次用户 ID 和设置。现在,每次控制器加载时我都会获取 userId,然后如果需要,我也会每次都查询数据库以获取它们的设置。

4

6 回答 6

11

关于安全的规则之一是你不应该尝试自己做。在不留下漏洞或后门的情况下正确地进行身份验证系统存在许多缺陷。因此,在这方面,您可能会考虑 .NET 附带的 SqlMembershipProvider。它可以与 MVC 一起使用,并提供获取角色和当前安全上下文的方法,易于设置和配置,并且比自己滚动更安全。

如果您不使用 SQL Server,您有几个选择。一种解决方案是使用 SQL Server Express 或 SQL Server Compact Edition 之类的东西来维护凭据。另一种解决方案是模仿 SqlMembrshipProvider 数据库架构,然后编写与该架构通信的自定义提供程序。

最后的选择是编写一个自定义 MembershipProvider 类。虽然这仍然是您自己的,但它会强制您进入 MembershipProvider 的结构,以便您可以在以后将其换成不同的(例如 ActiveDirectoryMembershipProvider),并提供用于与凭据和登录交互的通用接口,例如可以轻松使用内置的登录控件。

如果您已经在使用 MembershipProvider 并且正在询问是否存储其他用户特定的数据,那么我会建议 SqlProfileProvider 以及我上面提到的关于 SqlMembershipProvider 的所有警告。ProfileProvider 提供了一种结构,用于与当前登录的用户一起维护用户特定的数据。

了解更多信息:

于 2010-06-05T04:21:58.840 回答
1

您还可以实现自定义身份。它们很容易实现,它们让您可以在 Identity 中存储您想要的任何用户信息,然后将其存储在 Identity 放置的 cookie 中,因此您不必每次都访问数据库来获取该信息。

只需创建一个继承自 GenericIdentity 的新类,您就可以上路了。

你当然要小心你放了多少信息,因为它在一个 cookie 中,但通常你在这里谈论的情况下的用户相关信息不是那么大。

我们使用自定义身份来存储有关用户的一些信息,并且效果很好。

于 2010-06-02T18:04:12.483 回答
0

您可以在会话中存储一个对象,该对象包含所有必需的用户信息。您只需在要检索用户信息/配置文件的控制器、视图或其他基类中添加一个属性。这将是授权信息,而不是任何身份验证信息(例如表单身份验证)

于 2010-06-02T17:47:20.083 回答
0

您可以尝试“Windows Identity Foundation”。我已经在我的一个项目中使用它一段时间了。它允许“基于声明的身份验证”,这基本上意味着您可以指定“声明”,即在用户登录时描述用户的信息字符串。

登录后,可以从该HttpContext.Current.User字段中读取用户的声明。您还可以使用与基于角色的身份验证架构无缝集成的“角色”声明;这意味着您可以给用户一个“经理”角色声明,然后使用 `if (User.IsInRole("manager"))。

作为一个额外的好处,WIF 使得在其他应用程序中重复使用您的登录屏幕变得非常容易。

总而言之,它非常灵活,但是文档很差。我已经在 StackOverflow 上询问并回答了许多关于“Windows Identity Foundation”的问题。

于 2010-06-07T15:32:46.007 回答
0

过去我们已经多次这样做了。与 Thomas 提到的类似,我们通常所做的是基于 Microsoft SQL Memberhsip 提供程序实现一个新的成员资格提供程序来执行此操作。我们从基础 MembershipUser 类继承并添加我们希望在用户对象上拥有的任何自定义属性。您必须在 GetUser 实现上为 Membership 提供程序实现数据库读取,因此您可以将所需的额外属性合并到该数据库读取中。

如果您使用的是 SQL Server,Microsoft 已经发布了它的 2.0 代码。您可以在 Scott Gu 的博客上获得更多信息。

http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx

如果你想从头开始,他们在 MSDN 上也有很好的资源。

http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx

http://msdn.microsoft.com/en-us/library/6tc47t75.aspx

实现提供程序后,您可以将 Membership 用户添加到当前 Web 上下文的 Items 集合中,以便从您的代码中访问它。来自基本用户类的非扩展属性也可以像往常一样在请求线程上使用。

随着 Microsoft 发布 2.0 版本的源代码,我们发现它帮助我们减轻了对重新发明的一些担忧。您的实现要考虑的另一件事是根据您的场景,您可以绕过实现一些代码。如果您正在访问已经拥有凭证信息的后端系统,那么 CreateUser 代码就是一个示例。

于 2010-06-08T19:26:19.067 回答
0

您似乎对您的身份验证过程比较满意,但您想探索会话/设置的其他选项。

我的建议仅与设置有关(角色、偏好等)

在我看来,不得不遍历从 UI 到业务层再到数据库层再到数据库的整个技术堆栈有时有点矫枉过正。对于在会话期间不太可能更改的数据,这会增加很多开销...可能会发生几种数据转换(DB(关系格式)-> ORM-> Web 服务 XML 序列化-> Web 层反序列化) .

您可能会考虑一个不依赖于繁重的 RDBMS 系统或 ASP.NET 缓存/会话模型的会话系统。有些选项性能非常好并且可以很好地扩展。

您可以使用Ayende Rahien 的RavenDB(为 .NET 构建)。它的主要目标是提供对无模式 JSON 文档的低延迟、高性能访问。

使用此解决方案,您将在 Web 层设置 ravenDB,以便非常快速地访问数据。第一次验证和检索设置时,您会将用户 ID 和设置信息存储在此会话数据库中。之后每次加载控制器时,都可以访问设置数据,而无需返回 RDBMS。该数据库还可用于缓存其他与 Web 相关的数据。

至于安全性,无论您使用何种方法,设置数据都会进入 Web 层。此解决方案不会比其他选项更安全或更不安全(比未加密的 cookie 更安全)。如果需要,您可以加密会话数据 - 但这会再次增加您的开销。

只是要考虑的百万种选择中的另一种。

祝你好运,

让我们知道您的决定!

帕特里克。

于 2010-06-11T17:22:22.013 回答