【问题标题】:Get the current user, within an ApiController action, without passing the userID as a parameter在 ApiController 操作中获取当前用户,而不将用户 ID 作为参数传递
【发布时间】:2014-03-04 05:27:38
【问题描述】:

我们如何在安全的 ApiController 操作中获取当前用户,而不将 userName 或 userId 作为参数传递?

我们假设这是可用的,因为我们处于安全操作中。处于安全操作中意味着用户已经通过身份验证并且请求具有她的不记名令牌。鉴于 WebApi 已授权用户,可能有一种内置方式来访问 userId,而无需将其作为操作参数传递。

【问题讨论】:

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


【解决方案1】:

在 WebApi 2 中,您可以在 ApiController 的方法中使用 RequestContext.Principal

【讨论】:

  • 我们似乎没有那个属性。唔。也许我们使用的是旧版本的 WebApi。
  • @ShaunLuttin 好的,所以如果您使用的是 Web API 1,那么我相信 ApiController 上有一个 Prinicpal 属性。这只是访问 Request.Properties 集合的精美包装。主体对象存储在该字典中。
  • 别忘了using Microsoft.AspNet.Identity;
  • @DarrelMiller 有没有办法从代码的其他部分(不在控制器内)获得相同的(比如请求上下文)。
  • @AjayAradhya 只有当你通过它时。以前对 Web 框架的研究表明,使用静态属性访问请求上下文会导致各种架构问题。一开始很方便,但长期下来会很痛苦。
【解决方案2】:

您还可以使用ApiController 上的User 属性访问主体。

所以下面两种说法基本一致:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();

【讨论】:

  • 我正在尝试使用您在此处编写的内容,但 GetUserId() 函数始终返回 null。用户已通过身份验证,我正在传递一个不记名令牌,并且 ApiController 具有 [Authorize] 标头
  • GetUserId() 函数仅在用户拥有 NameIdentifier 声明时才返回 ID。有关如何解决此问题的示例,请在此处参考 Oswaldo 的回答:stackoverflow.com/questions/19505526
【解决方案3】:

提示在于 Webapi2 自动生成的账户控制器

将此属性与 getter 定义为

public string UserIdentity
        {
            get
            {
                var user = UserManager.FindByName(User.Identity.Name);
                return user;//user.Email
            }
        }

为了得到 UserManager - 在 WebApi2 中 - 像 Romans(读作 AccountController)那样做

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

这应该在 IIS 和自主机模式下兼容

【讨论】:

    【解决方案4】:

    以上建议都不适合我。以下是这样做的!

    HttpContext.Current.Request.LogonUserIdentity.Name
    

    我想有各种各样的场景,这个对我有用。我的场景涉及一个 AngularJS 前端和一个 Web API 2 后端应用程序,它们都在 IIS 下运行。我必须将两个应用程序设置为在 Windows 身份验证下独占运行。

    无需传递任何用户信息。浏览器和 IIS 交换已登录的用户凭据,并且 Web API 可以按需访问用户凭据(我假设来自 IIS)。

    【讨论】:

    • 注意,HttpContext.Current.Request.LogonUserIdentity 返回 WindowsIdentity。
    【解决方案5】:

    Karan Bhandari 的回答很好,但是项目中添加的 AccountController 很可能是 Mvc.Controller。要将他的答案转换为在 ApiController 中使用,请将 HttpContext.Current.GetOwinContext() 更改为 Request.GetOwinContext() 并确保添加了以下 2 个 using 语句:

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.Owin;
    

    【讨论】:

      【解决方案6】:

      在 .Net Core 中使用 User.Identity.Name 获取用户的 Name 声明。

      【讨论】:

      • User.Identity.Name 获取 name 声明的值。它不是特定于 Active Directory 的。
      • @Nate 感谢您的评论,我已修复它
      【解决方案7】:

      如果你使用的是 Asp.Identity UseManager,它会自动设置的值

      RequestContext.Principal.Identity.GetUserId()

      基于您在创建 IdentityDbContext 时使用的 IdentityUser

      如果您正在实施自定义用户表和 owin 令牌持有者身份验证,请查看我的答案。

      How to get user context during Web Api calls?

      希望它仍然有帮助。 :)

      【讨论】:

        【解决方案8】:
        string userName;
        string userId;
        if (HttpContext.Current != null && HttpContext.Current.User != null 
                && HttpContext.Current.User.Identity.Name != null)
        {
            userName = HttpContext.Current.User.Identity.Name;
            userId = HttpContext.Current.User.Identity.GetUserId();
        }
        

        或者根据 Darrel Miller 的评论,也许可以先用它来检索 HttpContext。

        // get httpContext
        object httpContext;
        actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContext);    
        

        另见:

        How to access HTTPContext from within your Web API action

        【讨论】:

        • 不要使用 HttpContext,因为它会限制您的托管选项并使您的代码难以测试。
        • 如果您是 Self-host 或 OwinHttpListener 托管,则 HttpContext 对象将不在字典中
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-11
        • 1970-01-01
        • 2021-07-31
        • 1970-01-01
        • 1970-01-01
        • 2012-12-17
        相关资源
        最近更新 更多