ASP.NET(OWIN)身份:如何从Web API控制器获取用户ID?

(使用VS2013 RTW,ASP.NET MVC5)

我已经看到很多关于如何在使用ASP.NET标识时向ApplicationUser类(和表)添加属性的文档。 但是我还没有看到有关如何通过外键映射到ApplicationUser表的内容的单独表的任何文档。

我已经成功地派生了我自己的Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext,现在我自己的“UserPreferences”表与我的SQL Server数据库中的各种“AspNet *”表和谐共存。 但是我并不清楚获取当前用户ID的最佳方法,以便向“UserPreferences”表中写入新行。 请注意,该项目是ASP.NET MVC,但我已经添加(并正在工作)Web API控制器。

我有一个工作解决scheme,这是:

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 

考虑到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)) 

我认为id字段(不是用户名)是在这个表中引用的正确的字段。 (我以为用户可能会更改他/她的用户名,而其他人则可能会假定其他用户的用户名,这就是为什么这两个字段都可能存在)。那么,我需要获取当前用户的ID以存储在“UserPreferences”表,这是上面的代码所做的。 但是做这个查找似乎效率低下。

重要的一点是,在System.Web.Mvc.Controller的上下文中,我可以这样做:

 User.Identity.GetUserId() (Runtime type of User.Identity: System.Security.Principal.GenericIdentity) 

但在System.Web.Http.ApiController(Web API)的上下文中,我不能因为该方法不存在(运行时types的User.Identity:System.Security.Claims.ClaimsIdentity),这就是为什么我必须依靠:

 User.Identity.Name 

并做额外的查找将名称转换为ID。 有没有人有任何build议如何可以改善? 我是否正在接近以正确的方式将用户数据写入分隔表的任务?

您应该能够通过身份1.0 RTW包中的相同扩展方法在MVC控制器和web api控制器上获得用户标识。

这是来自身份包的扩展:

 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); } } 

IIdentity是所有身份types的基础接口。 您可能需要添加“使用Microsoft.AspNet.Identity”才能看到扩展方法。

顺便说一句:关于为用户添加一个外部表,为什么不使用ApplicationUser并将导航属性添加到UserPreference让EF来处理他们的关系? 这将会更容易。

 ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, userName)); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, UserID)); 

ClaimTypes.NameIdentifier是函数User.Identity.GetUserId()

我正在使用索赔库方法:

 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); } 

最佳答案的简短描述:

  1. Install-Package Microsoft.AspNet.Identity.Core -Version 2.2.1
  2. var userId = User.Identity.GetUserId();

简单的解决scheme是:

 var user = await UserManager.FindAsync(model.UserName, model.Password); 

而user.id属性将包含你所需要的。