16

我想在经过身份验证的用户中存储额外的信息,以便我可以轻松访问它(例如 User.Identity.Id),而不仅仅是名称,因为我打算拥有该非唯一信息。

到目前为止,我已经收集到我应该寻求实现自定义主体和/或身份,但我不确定如何去做。我一直在寻找有关此事的文档和教程,但我在不同的地方找到了相关的东西,我发现它有点令人困惑。

我已经看到如何将自定义信息添加到用户数据属性中的身份验证 cookie,但我希望能够从依赖注入中受益,我可以使用主体和身份来进行单元测试。

如果我想实现自己的 Principal 或 Identity,我需要考虑哪些具体步骤?

在这种情况下,我能做的最简单的事情是什么(只需添加 ID 并保留所有默认值)?“默认值”将包括默认提供者(成员资格、角色等)。

我已经看到了另一个问题,但我很欣赏不会在两者之间留下任何漏洞的答案,例如示例中 AuthenticateRequest 事件中的角色魔术字符串。相反,我需要知道如何将默认 SqlRoleProvider 中的角色添加到当前用户:何时何地执行此操作,以及是否需要执行其他任何操作来将我的新类与其他默认提供程序连接起来。

能够转到示例 ASP.NET MVC 2 应用程序(例如,来自 Visual Studio 2010 模板),进行编辑并让它工作,真是太棒了。


编辑:我已经编辑了这个问题,以更好地表明我在这里几乎迷路了,所以我无法应付太高水平的答案。

PS:在我看来,在身份中使用 ID 而不是在主体中使用 ID 更有意义,尽管我之前在某种程度上已经说过这一点。

4

2 回答 2

20

之前已经提出并回答了这个问题: ASP.NET MVC - Set custom IIdentity or IPrincipal

但总结...

使用您要存储的其他属性创建一个自定义主体类:

Public Class CustomPrincipal
    Inherits System.Security.Principal.GenericPrincipal

    Private _eyeColor As String
    Public ReadOnly Property EyeColor As String
        Get
            Return _eyeColor
        End Get
    End Property

    Public Sub New(id As System.Security.Principal.IIdentity, roles As String(), eyeColor As String)
        MyBase.New(id, roles)
        _eyeColor = eyeColor            
    End Sub

End Class

修改 global.asax Global.Application_AuthenticateRequest 以使用您的自定义主体:

Protected Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As System.EventArgs)
    ...
    Dim roles() As String = {"examplerole"}         
    Context.User = new CustomPrincipal(Context.User.Identity, roles, "green")
End Sub

然后,当您想要引用这些属性之一时,在代码的其他地方执行以下操作:

CType(My.User.CurrentPrincipal, CustomPrincipal).EyeColor
于 2010-07-30T15:52:05.573 回答
2

你不能真的指望有人可以在几段中教你所有你不知道的关于 .NET 的知识。您可以在 MSDN http://msdn.microsoft.com/en-us/library/system.security.principal.genericprincipal.aspx阅读相当不错的示例,并深入研究该类及其在 Reflector 中的派生类 - 它没有什么特别之处.

角色只是您自己使用的名称字符串数组,在您的应用程序/服务器中。

话虽如此,您根本不必针对确切的 GenericPrincipal 导数。查看

HttpContext.Current.Items

它是一个 Hashtable,仅供您服务的请求免费使用 - 这意味着您可以在某一时刻说:

HttpContext.Current.Items["TokenUser"] = new MyThinUser(anything,I,want,there);

然后代码中的其他所有内容都可以:

var user = HttpContext.Current.Items["TokenUser"] as MyThinUser;

你就完成了。

将您需要/想要从认证代码传递到所有其他功能的所有内容存储在您的新类中。保留 User 属性不变(因此您可以窥视它而不必担心您更改了某些内容)。你可以随意简化或复杂化你的系统,但你保持完全的独立性。

例如,如果您有自己的身份验证并且只有几个级别的访问权限而不是枚举角色,您可以只携带良好的旧访问级别编号(作为字符串携带的枚举角色无论如何都是非常低效的)。

请记住,VS 中的自动生成样本通常适用于某些特定场景。因此,如果您看到用于用户管理的 SQL 提供程序,这并不意味着您实际上必须使用它 - 您仍然可以调用自己的存储过程来从您自己的 SQL 表中获取所需的内容。

于 2010-08-03T10:47:08.387 回答