如何在Web Api调用期间获取用户上下文?

Jos*_*ana 15 asp.net-web-api 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)
testa = Name: ClaimsIdentity,
testb = null,
testc = Bearer,
testd = true
Run Code Online (Sandbox Code Playgroud)

用户显然已通过身份验证,但我无法检索其用户ID.

更新4

我找到了答案,但我真的很不满意......

ClaimsIdentity identity = (ClaimsIdentity)User.Identity;
string username = identity.Claims.First().Value;
Run Code Online (Sandbox Code Playgroud)

这让我获得了没有任何数据库调用的用户名,但它看起来非常笨拙,将来很难支持.如果有人有更好的答案会爱.

如果我需要更改在路上发布的索赔怎么办?另外,当我真正需要用户的ID时,我必须进行数据库调用以将用户名转换为ID

小智 19

一种常见的方法是为您的ApiControllers创建一个基类,并利用ApplicationUserManager来检索您需要的信息.通过这种方法,您可以在一个位置保留用于访问用户信息的逻辑,并在控制器中重复使用它.

public class BaseApiController : ApiController
{
        private ApplicationUser _member;

        public ApplicationUserManager UserManager
        {
            get { return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
        }

        public string UserIdentityId
        {
            get
            {
                var user = UserManager.FindByName(User.Identity.Name);
                return user.Id; 
            }
        }

        public ApplicationUser UserRecord
        {
            get
            {
                if (_member != null)
                {
                    return _member ; 
                }
                _member = UserManager.FindByEmail(Thread.CurrentPrincipal.Identity.Name); 
                return _member ;
            }
            set { _member = value; }
        }
}
Run Code Online (Sandbox Code Playgroud)

  • 您可能希望将`abstract`关键字添加到此类,以保护它免受Web API自动路由的影响,并且因为不应该直接存在此类的实例. (2认同)