ASP.NET(OWIN)标识:如何从Web API控制器获取UserID?

时间:2013-10-21 21:58:13

标签: asp.net-mvc asp.net-web-api visual-studio-2013 owin asp.net-identity

(使用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控制器。

我有一个可行的解决方案,即:

            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)的上下文中,我不能,因为该方法不存在(User.Identity的运行时类型:System.Security.Claims.ClaimsIdentity)这就是为什么我必须相反依赖:

User.Identity.Name

并执行额外查找以将Name转换为ID。有没有人对如何改进这方面有任何建议?我是否正在以正确的方式处理将用户数据写入单独表格的任务?

5 个答案:

答案 0 :(得分:57)

您应该能够通过identity 1.0 RTW package中的相同扩展方法在MVC控制器和web api控制器上获取用户ID。

以下是身份包的扩展名:

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是所有身份类型的基本接口。您可能需要添加“使用Microsoft.AspNet.Identity”才能查看扩展方法。

BTW:关于为用户添加外表,为什么不使用ApplicationUser并将导航属性添加到UserPreference以让EF处理他们的关系?这会更容易。

答案 1 :(得分:45)

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()

的声明

答案 2 :(得分:11)

我使用了声明基础方法:

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

答案 3 :(得分:3)

最佳答案的简短描述:

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

答案 4 :(得分:0)

尝试过@Mastenka的答案,它什么也没给我。我检查了ClaimsIdentity,发现 声明类型为“ UserName”,因此,我使用“ UserName”作为ClaimsType获得了用户名。 希望有人能提供更多有关它的信息。 “ ClaimTypes.NameIdentifier”没有作用看起来很奇怪。 (ApiController,ASP MVC API)

\n