如何在 ASP.NET MVC 中实现自定义主体和身份?

发布于 2024-09-09 23:21:52 字数 911 浏览 2 评论 0原文

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

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

我已经了解了如何将自定义信息添加到用户数据属性中的身份验证 cookie,但我希望能够受益于单元测试的依赖项注入,我可以通过主体和身份来实现这一点。

如果我想实现自己的委托人或身份,我需要考虑哪些确切步骤?

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

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

如果能够访问示例 ASP.NET MVC 2 应用程序(例如,来自 Visual Studio 2010 模板),进行编辑并使其正常工作,那就太棒了。


编辑:我已经编辑了这个问题,以更好地表明我在这里迷失,所以我不能凑合太高级别的答案。

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

I want to store extra information in the authenticated user so that I can have it easily accessible (like User.Identity.Id, for example), instead of just the name, since I'm planning on having that non-unique.

So far I've gathered that I should look to implement custom Principal and/or Identity, but I'm not sure how to go about it. I've been looking for documentation and tutorials on the matter, but I've found related stuff in different places and I've found it a bit confusing.

I have seen how to add custom info to the authentication cookie in the user data property, but I'd like to have the benefit of dependency injection for unit testing, which I can have with the principal and identity.

What are the exact steps I need to consider if I want to implement my own Principal or Identity?

What would be the simplest I could do in this scenario (just add the ID and keep all the defaults in place)? "Defaults" would include the default providers (membership, roles, etc.).

I have seen the other question, but I'd appreciate answers that do not leave any holes in between, such as the roles magic strings in the AuthenticateRequest event in the examples. Instead I need to know how to add the roles from the default SqlRoleProvider to the current user: when and where to do it, and if I need to do anything else to connect my new classes with the other default providers.

It'd be awesome to be able to go to a sample ASP.NET MVC 2 application (from the visual studio 2010 template, for example), make the edits and have it work.


EDIT: I have edited the question to better show that I'm pretty much lost here, so I can't make do with too high level answers.

P.S.: It seems to me that it makes more sense to have the ID in the Identity instead of the principal, although I have, in a way, stated this before.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温柔嚣张 2024-09-16 23:21:52

这个问题之前已经被问过并回答过:
ASP.NET MVC - 设置自定义 IIdentity 或 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

This question has been asked and answered before:
ASP.NET MVC - Set custom IIdentity or IPrincipal

But to summarize...

Crate a custom principal class with the additional properites you want to store:

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

Modify global.asax Global.Application_AuthenticateRequest to use your custom principal:

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

Then elsewhere in your code when you want to refer to one of these properties do this:

CType(My.User.CurrentPrincipal, CustomPrincipal).EyeColor
夏有森光若流苏 2024-09-16 23:21:52

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

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

话虽如此,您实际上根本不必瞄准精确的 GenericPrincipal 导数。查看

HttpContext.Current.Items

It's a Hashtable for free use just for the request you are services - 这意味着在某一时刻你可以说:

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

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

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

然后你就完成了。

将您需要/想要从身份验证代码传递到所有其他函数的所有内容存储在您的新类中。保持 User 属性完好无损(这样您就可以查看它,而不必担心您更改了某些内容)。 Wihr 认为,您可以随意简化或复杂化您的系统,但您可以保持完全的独立性。

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

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

You can't realy expect that someone can teach you everything you don't know about .NET in a few paragraphs. You can read pretty good example at MSDN http://msdn.microsoft.com/en-us/library/system.security.principal.genericprincipal.aspx and dig through the class and it's derivatives in Reflector - there's nothing spectacularly special about it.

Roles are just a string arrray of names for your own use, in your app/server.

Having said that, you don't really have to aim at exact GenericPrincipal derrivative at all. Check out

HttpContext.Current.Items

It's a Hashtable for free use just for the request you are servicing - meaning that at one point you can do say:

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

and then everythere else in the code just do:

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

and you are done.

Store in your new class everything you need/want to pass around from the authentification code to all other functions. Leaves User property intact (so you can peek into it and not have to worry that you changed something). Wihr that you can simplify or complicate your system at will but you keep full independence.

For example if you have your own authentification and just a few levels of acces instead of enumerated roles you can just carry good old access level number (enumerated roles carried around as strings are very inefficient anyway).

Keep in mind that autogenned samples in VS are usually geared towards some particular scenario. So if you see SQL providers for user management that doesn't mean that you actually have to use it - you can still just call your own sproc to get what you need from your own table in SQL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文