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

     2023-03-31     234

关键词:

【中文标题】如何在 ASP.NET MVC 中实现自定义主体和身份?【英文标题】:How do I implement custom Principal and Identity in ASP.NET MVC? 【发布时间】:2011-03-17 11:30:25 【问题描述】:

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

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

我已经看到了如何在用户数据属性中将自定义信息添加到身份验证 cookie,但我希望在单元测试中获得依赖注入的好处,我可以通过主体和身份来获得。

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

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

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

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


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

P.S.:在我看来,在身份中使用 ID 而不是在主体中使用 ID 更有意义,尽管我之前在某种程度上说过。

【问题讨论】:

您目前是否已设置并运行表单身份验证和角色? 我愿意。我从 VS 2010 模板中的 MVC Web 应用程序(与 MVC Empty Web 应用程序相反)开始,因此它具有用于用户管理的所有默认 SQL 提供程序:包括成员资格和角色。但大部分都是在幕后完成的。按照惯例,因为它是 你不能只使用 Profile 支持来处理这种事情吗?这就是它的用途(与用户关联的额外数据) - 应该比我认为的“自定义用户”更简单 确实,但我想将它放在某种会话变量中,而不是每次都从存储中获取它。此外,除了身份验证 cookie UserInfo(这是我用作解决方法的方法)之外,我还想要一些可以与依赖注入一起进行测试的东西,比如 hanselman 所做的 hanselman.com/blog/… 【参考方案1】:

这个问题已经被问过并回答过: 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

【讨论】:

Seth - 你从哪里得到“绿色”?您是否在每个 Application_AuthenticateRequest 从数据库中检索它?您是否将其存储在会话变量中? @mga911 - 在这个例子中,“绿色”是硬编码的。在一个真正的网络应用程序中,我会从数据库中读取它,并可能将它存储在一个 cookie 中。在对 AuthenticateRequest 的其他调用中,可以从 cookie 中读取它以防止 db 调用。会话变量在这里不是一个选项,因为 AuthenticateRequest 在 SessionStart 之前被调用。【参考方案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 提供程序并不意味着您实际上必须使用它 - 您仍然可以调用自己的 sproc 来从您自己的 SQL 表中获取所需的内容。

【讨论】:

这是一个有趣的方法。

在 ASP.NET 5 (vNext) MVC 6 中实现自定义路由器

...按照theexampleintheRoutingproject解决了大部分问题,但是我对如何从该方法 查看详情

如何在 ASP.NET Core 中实现自定义模型验证?

】如何在ASP.NETCore中实现自定义模型验证?【英文标题】:ASP.NETCore-Createcustommodelvalidation【发布时间】:2016-07-1215:07:56【问题描述】:在以前版本的ASP.NETMVC中,向模型添加自定义验证的方法是实现IValidatableObject并实现您自己的Val... 查看详情

在 MVC 中实现自定义身份和 IPrincipal

】在MVC中实现自定义身份和IPrincipal【英文标题】:ImplementingaCustomIdentityandIPrincipalinMVC【发布时间】:2010-12-2510:29:21【问题描述】:我有一个基本的MVC2beta应用程序,我正在尝试实现自定义身份和主体类。我创建了实现IIdentity和IPr... 查看详情

如何在 WCF 服务中实现自定义身份验证

】如何在WCF服务中实现自定义身份验证【英文标题】:HowtoImplementcustomauthenticationinWCFservice【发布时间】:2019-12-1403:26:43【问题描述】:我想为具有自定义身份验证的移动应用程序创建WCFrestful服务。第一个请求应该是登录,特别... 查看详情

如何在 UIImagePicker 中实现自定义“使用”和“重拍”按钮?

】如何在UIImagePicker中实现自定义“使用”和“重拍”按钮?【英文标题】:Howtoimplementcustom\'Use\'and\'Retake\'buttoninUIImagePicker?【发布时间】:2011-03-2507:06:04【问题描述】:我的意思是,我已经关闭了相机控制器pickerCam.showsCameraContro... 查看详情

如何使用trackerenableddbcontext在asp.net mvc5和代码中的实体框架中实现审计跟踪

】如何使用trackerenableddbcontext在asp.netmvc5和代码中的实体框架中实现审计跟踪【英文标题】:Howtoimplementaudittrailinasp.netmvc5andentity-frameworkincodefirst,usingtrackerenableddbcontext【发布时间】:2019-12-0212:47:03【问题描述】:我正在使用实体... 查看详情

如何在 Asp.net mvc 或 Asp.net Core 中实现可搜索的 Dropdown?

】如何在Asp.netmvc或Asp.netCore中实现可搜索的Dropdown?【英文标题】:HowtoimplementDropdownwithsearchableinAsp.netmvcorAsp.netCore?【发布时间】:2021-12-0623:44:48【问题描述】:注意:在这里,在您执行任何其他操作之前,将这两个文件添加到... 查看详情

如何在 WordPress 中实现自定义标头的引导小部件代码?

】如何在WordPress中实现自定义标头的引导小部件代码?【英文标题】:HowtocanimplementbootstrapwidgetcodeforcustomheaderinWordPress?【发布时间】:2019-07-1703:22:25【问题描述】:我在网站上工作,我不是引导程序的专业人士。这是我的主题标... 查看详情

如何在 keras 中实现自定义指标?

】如何在keras中实现自定义指标?【英文标题】:howtoimplementcustommetricinkeras?【发布时间】:2016-10-0601:13:54【问题描述】:我得到这个错误:sum()得到了一个意外的关键字参数\'out\'当我运行这段代码时:importpandasaspd,numpyasnpimportkera... 查看详情

如何在 iPhone 中实现自定义相机功能? [关闭]

】如何在iPhone中实现自定义相机功能?[关闭]【英文标题】:HowtoimplementcustomcamerafunctionalityiniPhone?[closed]【发布时间】:2011-08-1605:07:13【问题描述】:我想开发一种功能,以便在iPhone应用程序中实现自定义相机功能,所以请给我... 查看详情

我们如何在 Laravel 中实现自定义的仅 API 身份验证

】我们如何在Laravel中实现自定义的仅API身份验证【英文标题】:HowdoweimplementcustomAPI-onlyauthenticationinLaravel【发布时间】:2020-09-1019:04:42【问题描述】:这不是一个非常需要答案的问题,但欢迎提供进一步的建议和答案和建议。我... 查看详情

如何在 ASP.Net MVC 中实现视频文件流式传输?

】如何在ASP.NetMVC中实现视频文件流式传输?【英文标题】:HowtoimplementvideofilestreaminginASP.NetMVC?【发布时间】:2017-07-0714:06:51【问题描述】:我想实现简单的视频文件流。有我的API控制器:[HttpGet][Route("api/VideoContent")]publicHttpRespons... 查看详情

如何在黄瓜中实现自定义监听器?

】如何在黄瓜中实现自定义监听器?【英文标题】:Howtoimplementcustomlistenersincucumber?【发布时间】:2021-12-2214:55:47【问题描述】:如何在cucumber中实现客户监听?哪个可以记录到控制台/报告失败方法的发生?使用黄瓜4.0注意:钩... 查看详情

如何在 TCPDF 中实现自定义字体

】如何在TCPDF中实现自定义字体【英文标题】:HowtoimplementcustomfontsinTCPDF【发布时间】:2011-07-1222:11:47【问题描述】:在TCPDF中,只有几种字体可供选择,用于创建pdf文件。我想将Tahoma设置为我的pdf字体。如何在TCPDF中包含Tahoma?... 查看详情

如何在canvas中实现自定义路径动画(代码片段)

...塞尔曲线,因此,这个动画也许是下面这个样子的:那么如何才能在canvas中实现这种动画效果呢?其实很简单,对于路径的处理svg非常在行,因此在canvas中实现自定义路径动画,我们需要借助svg的力量。创建Path制作动画前,先... 查看详情

如何在自定义 Spring 存储库中实现自定义方法? [复制]

】如何在自定义Spring存储库中实现自定义方法?[复制]【英文标题】:Howtoimplementcustommethodincustomspringrepository?[duplicate]【发布时间】:2016-03-2719:36:21【问题描述】:假设我想要一个方法,获取超级主客户,有id=0。我有客户类:@Ent... 查看详情

如何在 ASP.Net MVC3 中实现打印

】如何在ASP.NetMVC3中实现打印【英文标题】:HowtoimplementprintinginASP.NetMVC3【发布时间】:2012-11-1718:01:42【问题描述】:作为给定项目列表中我当前任务的一部分,用户可以选择其中的一些并调用“打印”不选择的项目。对于每个... 查看详情

如何在 JSON.NET 中实现自定义 JsonConverter?

】如何在JSON.NET中实现自定义JsonConverter?【英文标题】:HowtoimplementcustomJsonConverterinJSON.NET?【发布时间】:2011-12-2306:02:32【问题描述】:我正在尝试扩展此处给出的JSON.net示例http://james.newtonking.com/projects/json/help/CustomCreationConverter.... 查看详情