asp.net-mvc ASP.NET (OWIN) 身份:如何从 Web API 控制器获取用户 ID?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19505526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET (OWIN) Identity: How to get UserID from a Web API controller?
提问by BenjiFB
(Using VS2013 RTW, ASP.NET MVC5)
(使用 VS2013 RTW、ASP.NET MVC5)
I've seen lots of documentation on how to add properties to the ApplicationUser class (and table) when using ASP.NET identity. But I haven't seen any documentation on how to have a separate table with content that maps to the ApplicationUser table via a foreign key.
我看过很多关于如何在使用 ASP.NET 标识时向 ApplicationUser 类(和表)添加属性的文档。但是我还没有看到任何关于如何拥有一个单独的表的文档,该表的内容通过外键映射到 ApplicationUser 表。
I've successfully derived my own Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext, and now my own "UserPreferences" table coexists in harmony with the various "AspNet*" tables in my SQL Server database. But I'm not clear on the best way to get the current user's ID so as to write a new row to the "UserPreferences" table. Note that the project is ASP.NET MVC, but I've added (and am working inside of) a Web API controller.
我已经成功地导出了我自己的 Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext,现在我自己的“UserPreferences”表与我的 SQL Server 数据库中的各种“AspNet*”表和谐共存。但我不清楚获取当前用户 ID 以便将新行写入“UserPreferences”表的最佳方法。请注意,该项目是 ASP.NET MVC,但我已添加(并在其中工作)一个 Web API 控制器。
I have a working solution, which is:
我有一个可行的解决方案,即:
var uman = new Microsoft.AspNet.Identity.UserManager<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new App1.Data.App1DbContext()));
var uident = User.Identity;
var userobject = uman.FindByNameAsync(uident.Name);
var userid = userobject.Result.Id;
// (Perform new row creation including the userid we just looked up
Consider that the AspNetUsers table (as defined by the Identity framework) consists of these fields:
考虑 AspNetUsers 表(由 Identity 框架定义)由以下字段组成:
-id (PK, nvarchar(128) - seems to contain a GUID, not sure why not an autoincrement integer, but I assume there are reasons for this)
-Username (nvarchar(max))
-PasswordHash (nvarchar(max))
-SecurityStamp (nvarchar(max))
I think that the id field (not the username) is the correct field to reference in this table. (I was thinking that a user may change his/her username, and someone else could then assume the other user's username, which is why both fields are there likely.) So then, I need to get the current user's ID for storage in the "UserPreferences" table, which is what the above code does. But it seems inefficient to have to do this lookup.
我认为 id 字段(不是用户名)是该表中要引用的正确字段。(我在想一个用户可能会改变他/她的用户名,然后其他人可以假设另一个用户的用户名,这就是为什么两个字段都可能存在的原因。)那么,我需要获取当前用户的 ID 以存储在“UserPreferences”表,这就是上面代码所做的。但是必须执行此查找似乎效率低下。
An important point is that in the context of a System.Web.Mvc.Controller, I can do:
重要的一点是,在 System.Web.Mvc.Controller 的上下文中,我可以执行以下操作:
User.Identity.GetUserId()
(Runtime type of User.Identity: System.Security.Principal.GenericIdentity)
But in the context of a System.Web.Http.ApiController (Web API), I cannot because that method does not exist (runtime type of User.Identity: System.Security.Claims.ClaimsIdentity) which is why I must rely instead on:
但是在 System.Web.Http.ApiController(Web API)的上下文中,我不能,因为该方法不存在(User.Identity 的运行时类型:System.Security.Claims.ClaimsIdentity),这就是为什么我必须依赖:
User.Identity.Name
and do the extra lookup to convert Name to ID. Does anyone have any suggestions for how this can be improved? Am I approaching the task of writing user data to separate tables in the correct way?
并进行额外的查找以将名称转换为 ID。有没有人对如何改进这种情况有任何建议?我是否正在以正确的方式完成将用户数据写入单独表的任务?
回答by Hongye Sun
You should be able to get user id on both MVC controller and web api controller by same extension method in identity 1.0 RTW package.
您应该能够通过身份 1.0 RTW 包中的相同扩展方法在 MVC 控制器和 web api 控制器上获取用户 ID 。
Here is the extensions from identity package:
以下是身份包的扩展:
namespace Microsoft.AspNet.Identity
{
public static class IdentityExtensions
{
public static string FindFirstValue(this ClaimsIdentity identity, string claimType);
public static string GetUserId(this IIdentity identity);
public static string GetUserName(this IIdentity identity);
}
}
The IIdentity is the base interface for all identity types. You may need to add "using Microsoft.AspNet.Identity" in order to see the extension method.
IIdentity 是所有身份类型的基本接口。您可能需要添加“使用 Microsoft.AspNet.Identity”才能查看扩展方法。
BTW: regarding adding a foreign table for user, why not using ApplicationUser and add navigation property to UserPreference to let EF to handle their relationship? That will be easier.
顺便说一句:关于为用户添加外部表,为什么不使用 ApplicationUser 并将导航属性添加到 UserPreference 以让 EF 处理它们的关系?那会更容易。
回答by Oswaldo Alvarez
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, UserID));
ClaimTypes.NameIdentifieris the claim for the function User.Identity.GetUserId()
ClaimTypes.NameIdentifier是函数的声明 User.Identity.GetUserId()
回答by Mastenka
I'm using claim base approach:
我正在使用索赔基础方法:
private ApplicationUser GetCurrentUser(ApplicationDbContext context)
{
var identity = User.Identity as ClaimsIdentity;
Claim identityClaim = identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
return context.Users.FirstOrDefault(u => u.Id == identityClaim.Value);
}
回答by neustart47
Short description for the best answer:
最佳答案的简短说明:
Install-Package Microsoft.AspNet.Identity.Core -Version 2.2.1var userId = User.Identity.GetUserId();
Install-Package Microsoft.AspNet.Identity.Core -Version 2.2.1var userId = User.Identity.GetUserId();
回答by IHAFURR
Tried @Mastenka answer and it gave me nothing. I checked ClaimsIdentity and there were claims type "UserName", so as a result, I get username by using "UserName" as ClaimsType. Hope someone will give more info about it. It looks strange that "ClaimTypes.NameIdentifier" had no effect. (ApiController, ASP MVC API)
试过@Mastenka 的答案,但它什么也没给我。我检查了 ClaimsIdentity 并且有声明类型“UserName”,因此,我通过使用“UserName”作为 ClaimsType 来获取用户名。希望有人能提供更多有关它的信息。“ClaimTypes.NameIdentifier”没有效果看起来很奇怪。(ApiController, ASP MVC API)
var userName = ((ClaimsIdentity)RequestContext.Principal.Identity).Claims.FirstOrDefault(cl => cl.Type == "UserName")?.Value;

