116

How do we get the current user, within an secure ApiController action, without passing the userName or userId as a parameter?

We assume that this is available, because we are within a secure action. Being in a secure action means that the user has already authenticated and the request has her bearer token. Given that WebApi has authorized the user, there may be a built in way to access the userId, without having to pass it as an action parameter.

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467

8 Answers8

159

In WebApi 2 you can use RequestContext.Principal from within a method on ApiController

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • 1
    We don't have that property, it seems. Hmm. Maybe we are using an old version of WebApi. – Shaun Luttin Feb 07 '14 at 03:11
  • 2
    @ShaunLuttin Ok, so if you are using Web API 1 then you I believe there is a Prinicpal property on ApiController. This is just a fancy wrapper around accessing the Request.Properties collection. The principal object is stored in that dictionary. – Darrel Miller Feb 07 '14 at 03:25
  • Thank God for this answer. Been spending the last 2 hours trying to find where the new identity property was for the context. – Xipooo Jan 05 '16 at 18:44
  • 6
    Just don't forget `using Microsoft.AspNet.Identity;` – Overlord Nov 24 '16 at 08:06
  • @Overlord Or any other piece of middleware that sets the appropriate value in the request.Properties dictionary. – Darrel Miller Nov 24 '16 at 14:11
  • which current user would it be? the user under which the Web API services are running? – user1451111 Dec 14 '17 at 07:38
  • 1
    @DarrelMiller is there a way to get the same (say request context) from other parts of the code (not within controller). – Nameless Aug 28 '18 at 06:53
  • 2
    @AjayAradhya Only if you pass it there. Previous efforts on web frameworks have shown that using static properties to access request context causes all kinds of architectural problems. It's convenient at first but it causes soooooo much pain long term. – Darrel Miller Aug 28 '18 at 13:44
  • Hey thanks a lot! I was wondering all over the web trying to find a static ancestor for web api calls. You saved my day. Will pass it as parameter wherever required :) – Nameless Aug 29 '18 at 06:35
  • If you are not able to find the property then its possible that you are using the static Class RequestContext, the RequestContext.Principal property is on the filterContext parameter when you override the AuthorizeAttribute. e.g.; filterContext.RequestContext.Principal – user1131926 Oct 03 '19 at 11:12
42

You can also access the principal using the User property on ApiController.

So the following two statements are basically the same:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();
Patrick
  • 17,669
  • 6
  • 70
  • 85
  • 15
    I am trying to use what you've written here but the GetUserId() function always returns null. The user is auth'd, I'm passing a bearer token, and the ApiController has the [Authorize] header – Joshua Ohana Feb 22 '15 at 13:52
  • 1
    The GetUserId() function returns an ID only if the user has a NameIdentifier claim. For an example of how to resolve this, refer to Oswaldo's answer here: https://stackoverflow.com/questions/19505526 – jramm May 16 '20 at 02:24
16

Hint lies in Webapi2 auto generated account controller

Have this property with getter defined as

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

and in order to get UserManager - In WebApi2 -do as Romans (read as AccountController) do

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

This should be compatible in IIS and self host mode

Karan Bhandari
  • 370
  • 3
  • 12
11

None of the suggestions above worked for me. The following did!

HttpContext.Current.Request.LogonUserIdentity.Name

I guess there's a wide variety of scenarios and this one worked for me. My scenario involved an AngularJS frontend and a Web API 2 backend application, both running under IIS. I had to set both applications to run exclusively under Windows Authentication.

No need to pass any user information. The browser and IIS exchange the logged on user credentials and the Web API has access to the user credentials on demand (from IIS I presume).

kannankeril
  • 187
  • 1
  • 6
7

Karan Bhandari's answer is good, but the AccountController added in a project is very likely a Mvc.Controller. To convert his answer for use in an ApiController change HttpContext.Current.GetOwinContext() to Request.GetOwinContext() and make sure you have added the following 2 using statements:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
Mohsen Esmailpour
  • 11,224
  • 3
  • 45
  • 66
Jeff Leach
  • 126
  • 1
  • 4
6

In .Net Core use User.Identity.Name to get the Name claim of the user.

Venkatesh Muniyandi
  • 5,132
  • 2
  • 37
  • 40
3

If you are using Asp.Identity UseManager, it automatically sets the value of

RequestContext.Principal.Identity.GetUserId()

based on IdentityUser you use in creating the IdentityDbContext.

If ever you are implementing a custom user table and owin token bearer authentication, kindly check on my answer.

How to get user context during Web Api calls?

Hope it still helps. :)

Community
  • 1
  • 1
pampi
  • 517
  • 4
  • 8
1
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();
}

Or based on Darrel Miller's comment, maybe use this to retrieve the HttpContext first.

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

See also:

How to access HTTPContext from within your Web API action

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467