Leonardo
Leonardo

Reputation: 11401

Token Authentication- Set custom User Property

I want to achieve something like described here, but i have 2 problems: on the constructor of my controller, both HttpContext and therefore, User, are null, and i can't seem to get where that UserManager<T> class...

On my controllers action i can get the User and HttpContext, but i don't want to handle Claims conversion case-by-case! I would like to create a "BaseController", there have a "MyExtendedUserPrincipal", and on my actions only read stuff from it...

I'm not using the regular SQL user management middleware... i think thats why i can't get a hold of the UserManager<T>

Upvotes: 0

Views: 476

Answers (1)

M&#233;toule
M&#233;toule

Reputation: 14482

The UserManager<T> class doesn't come out of the box, you have to define it yourself. You can either use the default implementation, or define your own class if you need to.

For example:

MyUserStore.cs

This is where the users come from (e.g. a DB), and where you can retrieve your own user from any claim from the ClaimsPrincipal.

public class MyUserStore: IUserStore<MyUser>, IQueryableUserStore<MyUser>
{
    // critical method to bridge between HttpContext.User and your MyUser class        
    public async Task<MyUser> FindByIdAsync(string userId, CancellationToken cancellationToken)
    {
        // that userId comes from the ClaimsPrincipal (HttpContext.User)
        var user = _users.Find(userId);
        return await Task.FromResult(user);
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)        
{
    // you'll need both a user and a role class. You can also implement a RoleStore if needed
    services
        .AddIdentity<MyUser, MyRole>()
        .AddUserStore<MyUserStore>();

    services.Configure<IdentityOptions>(options =>
    {
        // This claim will be used as userId in MyUserStore.FindByIdAsync
        options.ClaimsIdentity.UserIdClaimType = ClaimTypes.Name;
    });
}

MyController .cs

Then, in your controller, you can access the UserManager<MyUser> class:

public class MyController : Controller
{
    private readonly UserManager<User> _userManager;
    public MyController(UserManager<User> userManager)
    {
        _userManager = userManager;
    }


    [HttpGet("whatever")]
    public async Task<IActionResult> GetWhatever()
    {
        // this will get your user from the UserStore, 
        // based on the ClaimsIdentity.UserIdClaimType from the ClaimsPrincipal
        MyUser myUser = await _userManager.GetUserAsync(User);
    }
}

Upvotes: 1

Related Questions