2

in the WebApi I can get the current user using AspIdentity that way

User.Identity.GetUserId<long>();

However, The service Layer doesn't know about the AspIdentity. And I don't want to passe the current user as paramettre for all the methodes.

In other word, what pattern I can use to get the current user wherever I want.

The reason for this is to log all the activity the current user is doing in the application.

  • It doesn't need to know about `AspIdentity`. You could pass the `IPrincipal` retrieved from `User` higher up down through to lower layers. Otherwise the only thing left is to use the static `HttpContext` which would be an anti-pattern of sorts. – Nkosi Mar 25 '16 at 16:33
  • @Nkosi isn't there a common way to do that? Like using this System.Security.Claims.ClaimsPrincipal.Current? my related question I'm researching https://stackoverflow.com/questions/53092899/i-cant-access-my-logged-in-user-in-my-data-access-layer-identity-server-4-and – Dawood Awan Oct 31 '18 at 23:03

2 Answers2

1

APIs are intended to be stateless, you may use the current logged in user, but you may have a 3rd party application accessing your API. Because it is stateless the current user is handled differently than with standard web calls.

Long story short: however you're authenticating your API users, you need to pass the username/userID down into the service layer. The good news is that once you have this setup, you can use the same service layer methods for API and non-API calls.

jhilden
  • 12,207
  • 5
  • 53
  • 76
0

Finally this is how I implemented it.

In the Framework Layer (a comun independent project) I added this:

public interface ICurrentContextProvider<T>
{
    T GetCurrentUser();      
}

In the API I Added the implementation of this interface, something like :

public  ApplicationUser GetCurrentUser()
{
     return _usersService.FindByIdAsync(Convert.ToInt64(HttpContext.Current.User.Identity.GetUserId())).Result;
}

And As the all other layers know about the Framework Layer I can call it anywhere without any reference to AspIdentity and without passing the Current user to all my functions.

Note: I make it a generic because of the following: 1-Framework (common layer) doesn't know about application user 2-I can get any other type from the context like the ApplicationUserId which is Long.