在数据库中存储Windows SID以进行查找

时间:2009-10-27 03:17:57

标签: sql database-design asp.net-membership

我有一个ASP.NET MVC应用程序,我需要允许客户根据他们的环境配置MembershipProviders,但仍然能够将该MembershipUser映射到我们数据库中的具体用户模型。

Membership.GetUser()将允许我访问已登录用户的Membership.ProviderUserKey。我可以使用它来关联用户记录。我们的自定义SQL提供程序将只返回User.Id,但AD是另一回事。在这种情况下,ProviderUserKeyIdentityReference

这些查找将经常发生,您可以想象(尽管缓存可以帮助减少数据库级别的查找)。

我无法决定哪条路线更好:将SID存储为varbinary或varchar列。此列不是主键,也不具有聚簇索引。知道我可以很好地索引字符串,并且以字符串格式读取SID肯定比二进制更好。有谁愿意分享他们如何解决这种情况?


更新

我不知道在发布之前我在搜索时错过了this SO question,但似乎很清楚,ActiveDirectoryMembershipProviderActiveDirectoryMembershipUser并未完全删除就像今天它们存在一样。

回答SO问题linked the following article,其中陈述如下:

  

a的相对标识符部分   SID相对于域是唯一的,   所以如果域名发生变化,则相对   标识符也会发生变化。

     

因此当User对象从一个移动时   域到另一个,一个新的SID必须   为用户帐户生成的   存储在Object-SID属性中。

但是,每个组和用户都有一个Object-GUID,即使移动了帐户,它也永远不会改变。因此,我应该在我的User类中使用Object-GUID,而不是Object-SID。否则,某人的用户记录如果被移动就会被放弃,从而打破他们的主体与他们创建的数据之间的关系。

不幸的是,ActiveDirectoryMembershipUser不允许我使用Object-GUID。因此,我要么必须在ActiveDirectoryMembershipUser完成工作后将SID转换为GUID,要么创建我自己的MembershipProvider,以便在现场完成我需要的所有工作。不幸的是,这意味着我可能需要通过ActiveDirectoryMembershipProvider复制已为我完成的工作。

3 个答案:

答案 0 :(得分:6)

Microsoft将SID存储为sys.server_principals

中的varbinary(85)

这也是一个独特的列,所以它必须有一个索引......

答案 1 :(得分:1)

用户名是您要索引的最后一件事。

当您将用户从一个域更改为另一个域时,SID仅在AD中更改。 RID分为两组 - 内置(<1000)和用户RID。管理员,访客等预定义用户始终具有相同的RID。

如果你想处理用户的移动等,那么GUID就是你的选择。

用户名和组管理中随时可以更改用户名。

这与对象名称不同,对象名称是不变的,但我不认为在森林中强制要求唯一。您可以拥有任意数量的John Smith用户。

我会查看ADSI对象。这些是COM对象,应该可以从ASP访问。 MSDN解释得很好。 ADSearch对象可用于从GUID返回用户属性(例如,包括DN)。

答案 2 :(得分:-3)

听起来你要让它变得比它需要的困难得多。你需要什么SID或GUID?您已经为ActiveDirectory中维护的用户帐户提供了唯一且完全可读的标识符。

它被称为“用户名”。希望它与用户“用户”表中存储的用户名相同。

您的应用只需要知道该用户名是否已成功通过ActiveDirectory进行身份验证。因此,如果他们成功登录 - 您只需存储他们在会话变量中进行身份验证的事实。

如果将它们配置为使用db用户登录,则成功设置相同的Session变量,表明它们已成功登录。

没有花哨的GUID或SID ......简单。