如何在WebApi调用期间获取用户上下文



我有一个web前端调用ASP web Api 2后端。身份验证使用ASP标识进行管理。对于我正在创建的一些控制器,我需要了解拨打电话的用户。我不想创建一些奇怪的模型来传递,包括用户的身份(我甚至不将其存储在客户端中)。

所有对API的调用都是使用承载令牌授权的,我认为控制器应该能够基于此确定用户上下文,但我不知道如何实现。我已经搜索过了,但我不知道我到底在搜索什么,也没有找到任何相关的东西。我会选择。。。

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

更新

我发现下面看起来很有希望。。。但该值始终为null!我的控制器继承自ApiController,并具有Authorize标头。

var userid = User.Identity.GetUserId();

更新2

我还在ApiController操作中尝试了Get the current user中的所有解决方案,没有将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();
    }
testa = Name: ClaimsIdentity,
testb = null,
testc = Bearer,
testd = true

用户显然已通过身份验证,但我无法检索到他们的userID。

更新4

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

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

这让我在没有任何数据库调用的情况下获得了用户名,但这似乎很烦人,将来很难支持。如果有人有更好的答案,我会很高兴的。

如果我需要更改以后发布的索赔,该怎么办?另外,每当我真正需要用户的id时,我都必须调用db将用户名转换为id

一种常见的方法是为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; }
        }
}

我使用自定义用户身份验证(我不使用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调用中检索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()

相关内容

  • 没有找到相关文章

最新更新