在 ApiController 操作中获取当前用户,而不将用户 ID 作为参数传递
Posted
技术标签:
【中文标题】在 ApiController 操作中获取当前用户,而不将用户 ID 作为参数传递【英文标题】:Get the current user, within an ApiController action, without passing the userID as a parameter 【发布时间】:2014-03-04 05:27:38 【问题描述】:我们如何在安全的 ApiController 操作中获取当前用户,而不将 userName 或 userId 作为参数传递?
我们假设这是可用的,因为我们处于安全操作中。处于安全操作中意味着用户已经通过身份验证并且请求具有她的不记名令牌。鉴于 WebApi 已授权用户,可能有一种内置方式来访问 userId,而无需将其作为操作参数传递。
【问题讨论】:
请看这个答案:***.com/a/26453782/3290276 添加声明成功了 【参考方案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 的回答:***.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 对象将不在字典中以上是关于在 ApiController 操作中获取当前用户,而不将用户 ID 作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章
用户(IPrincipal)在使用 Web Api 2.1 和 Owin 的 ApiController 的构造函数中不可用
从 MVC 控制器动作调用 APIController 动作
无法从 apicontroller 中的 OwinContext 获取 UserManager