(使用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
Run Code Online (Sandbox Code Playgroud)
考虑到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))
Run Code Online (Sandbox Code Playgroud)
我认为id字段(不是用户名)是此表中引用的正确字段.(我当时认为用户可能会更改他/她的用户名,然后其他人就可以假设其他用户的用户名,这就是为什么两个字段都可能存在的原因.)那么,我需要获取当前用户的存储空间ID. "UserPreferences"表,这是上面的代码所做的.但是,进行此查找似乎效率低下.
重要的一点是,在System.Web.Mvc.Controller的上下文中,我可以这样做:
User.Identity.GetUserId()
(Runtime type of User.Identity: System.Security.Principal.GenericIdentity) …
Run Code Online (Sandbox Code Playgroud) asp.net-mvc asp.net-web-api owin visual-studio-2013 asp.net-identity
我有一个Web前端调用ASP Web Api 2后端.使用ASP Identity管理身份验证.对于我正在创建的一些控制器,我需要知道用户正在进行呼叫.我不想创建一些奇怪的模型来传递,包括用户的身份(我甚至不存储在客户端).
所有对API的调用都是使用持票令牌授权的,我的想法是控制器应该能够根据这个确定用户上下文,但我不知道如何实现.我搜索过,但我不知道我在搜索什么,但没有发现任何相关内容.我想要......
public async Task<IHttpActionResult> Post(ApplicationIdentity identity, WalkthroughModel data)
Run Code Online (Sandbox Code Playgroud)
更新
我发现下面看起来很有希望...但是值总是为空!我的控制器继承自ApiController并具有Authorize标头.
var userid = User.Identity.GetUserId();
Run Code Online (Sandbox Code Playgroud)
更新2
我还尝试了在ApiController操作中获取当前用户的所有解决方案,而没有将userID作为参数传递但是没有工作.无论我获得的身份是有效和身份验证的,但具有空UserID
更新3
这就是我现在所处的位置.
[Authorize]
[Route("Email")]
public async Task<IHttpActionResult> Get()
{
var testa = User.Identity.GetType();
var testb = User.Identity.GetUserId();
var testc = User.Identity.AuthenticationType;
var testd = User.Identity.IsAuthenticated;
return Ok();
}
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)testa = Name: ClaimsIdentity, testb = null, testc = Bearer, testd = true
用户显然已通过身份验证,但我无法检索其用户ID.
更新4
我找到了答案,但我真的很不满意......
ClaimsIdentity identity = (ClaimsIdentity)User.Identity;
string username = identity.Claims.First().Value;
Run Code Online (Sandbox Code Playgroud)
这让我获得了没有任何数据库调用的用户名,但它看起来非常笨拙,将来很难支持.如果有人有更好的答案会爱. …
如果您位于控制器上下文中,则可以访问当前经过身份验证的用户.在ApiController操作中获取诸如获取当前用户之类的文章,而不将userID作为参数传递.
但是,如果我的控制器调用一个服务(同一个程序集),但在这里我没有控制器上下文.
实际获得经过身份验证的用户的最佳方法是什么?
我正在研究这个WebAPI项目,我需要为它创建单元测试.项目的基础是使用VS 2010创建的,然后添加了WebApi模块.
控制器的工作方式有点妨碍测试/模拟.我正在使用xUnit和Moq,但绝对没有必要坚持使用这两个.
应用程序使用特定对象来处理数据库访问,因此我有controllerObject及其构造函数需要DataAccessObject
我在模拟控制器/数据访问对时遇到问题.我试图运行的第一个测试是一个GetAllFromDataBase,但我真的不知道如何做到这一点.
编辑:
我做了Cuong Le告诉我的事情,整个现在正在移动,我真的很喜欢它.但我难以接受另一个问题.要访问API,有一个用户名/密码对,我的控制器使用Thread.CurrentPrincipal.Identity.Name; 现在我需要设置这个值才能完全正常工作.
还有valueServiceMock.Setup(service => service.GetValues()).Returns(new [] {"value1","value2"});
似乎不起作用.因为代码试图访问数据库,并且因为它无法获得有效的用户名而无法获取任何内容