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

时间:2015-02-22 12:33:54

标签: asp.net-web-api asp.net-identity

我有一个Web前端调用ASP Web Api 2后端。使用ASP Identity管理身份验证。对于我正在创建的一些控制器,我需要知道用户正在进行呼叫。我不想创建一些奇怪的模型来传递,包括用户的身份(我甚至不存储在客户端)。

所有对API的调用都是使用持票令牌授权的,我的想法是控制器应该能够根据这个来确定用户上下文,但我不知道如何实现。我搜索过,但我不知道我在搜索什么,但没有发现任何相关内容。我想找点像......

public async Task<IHttpActionResult> Post(ApplicationIdentity identity, WalkthroughModel data)

更新

我发现下面看起来非常有前景......但是值总是为空!我的控制器继承自ApiController,并有一个Authorize标头。

var userid = User.Identity.GetUserId();

更新2

我也尝试了Get the current user, within an ApiController action, without passing the userID as a parameter中的所有解决方案,但都没有效果。无论我获得的身份是有效和身份验证的,但具有空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();
    }
testa = Name: ClaimsIdentity,
testb = null,
testc = Bearer,
testd = true

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

更新4

我找到了答案,但我真的很不高兴......

ClaimsIdentity identity = (ClaimsIdentity)User.Identity;
string username = identity.Claims.First().Value;

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

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

1 个答案:

答案 0 :(得分:1)

我使用自定义用户身份验证(我不使用AspIdentity,因为我现有的用户表字段与IdentityUser属性有很大不同),并创建ClaimsIdentity传递我的表UserID和UserName以在API调用上验证我的持有者令牌。

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        User user;
        try
        {
            var scope = Autofac.Integration.Owin.OwinContextExtensions.GetAutofacLifetimeScope(context.OwinContext);
            _service = scope.Resolve<IUserService>();

            user = await _service.FindUserAsync(context.UserName);

            if (user?.HashedPassword != Helpers.CustomPasswordHasher.GetHashedPassword(context.Password, user?.Salt))
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
        }
        catch (Exception ex)
        {
            context.SetError("invalid_grant", ex.Message);
            return;
        }

        var properties = new Dictionary<string, string>()
        {
            { ClaimTypes.NameIdentifier, user.UserID.ToString() },
            { ClaimTypes.Name, context.UserName }
        };

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        properties.ToList().ForEach(c => identity.AddClaim(new Claim(c.Key, c.Value)));

        var ticket = new AuthenticationTicket(identity, new AuthenticationProperties(properties));

        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(identity);
    }

以及如何使用ClaimsIdentity在User ApiController Details call上检索我的User表详细信息。

    [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
    [Route("Details")]
    public async Task<IHttpActionResult> Details()
    {
        var user = await _service.GetAsync(RequestContext.Principal.Identity.GetUserId<int>());
        var basicDetails = Mapper.Map<User, BasicUserModel>(user);

        return Ok(basicDetails);
    }

注意 ClaimTypes.NameIdentifier = GetUserId()和ClaimTypes.Name = GetUserName()