Search code examples
asp.net-coreasp.net-identityasp.net-core-webapiusermanager

How to use ASP.NET Core Identity UserManager<ApplicationUser> through static method to get Identity User data from DB


I have created an API (ASP.NET core 6) and I have also used Identity framework for user management. Admin can make users active or inactive. so I want to check if the user is active or not in each API call. So I have created an extension method and I call this static method in onAuthorization method in custom authorize attribute. There I try to decode the token and get user Id from token. Using the user id I call the extension method and there I want to get the user from DB and check the user status(active/inactive). However I am facing the problem of using UserManager (initializing) since it is a static method. Please can somebody show me how to achive this?

Custom Authorize Attribute:

public void OnAuthorization(AuthorizationFilterContext context)
    {
        var result = AuthExtension.ValidateUserStatus(context.HttpContext);
        if(result)
            return;
        else
            context.Result = new UnauthorizedResult();
    }

Extension Method:

public static bool ValidateUserStatus(HttpContext context)
    {
        var user = context.User;
        var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
        if(authHeader == null) return false;

        var token = authHeader.Split(" ")[1];
        var handler = new JwtSecurityTokenHandler();
        var securityToken = handler.ReadToken(token) as JwtSecurityToken;
        var userId = user.FindFirstValue("sid");

        var _userManager = new UserManager<User>(new UserStore<User>(new ApplicationDbContext(new DbContextOptions<ApplicationDbContext>(), new HttpContextAccessor())), null, new PasswordHasher<User>(), null, null, null, null, null, null);
        var dbUser = _userManager.FindByIdAsync(userId).Result;
        if (dbUser == null) return false;
        if (dbUser.RecordStatus == Domain.Entities.Enums.RecordStatus.Deleted) return false;

        return true;
    }

Solution

  • It seems that the initializing step causes the issue. If you have configured Identity services in Program.cs, you can directly call it in your method. Here is the reference link.

    Also, I think you can move the initializing step to the OnAuthorization method:

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var userManager = context.HttpContext.RequestServices.GetService<UserManager<User>>();
        var result = AuthExtension.ValidateUserStatus(context.HttpContext, userManager);
        if (result)
            return;
        else
            context.Result = new UnauthorizedResult();
    }
    

    and change the Extension method to:

    public static bool ValidateUserStatus(HttpContext context, UserManager<User> userManager)
    {
        .
        .
        .
        //var _userManager = new UserManager<User>(new UserStore<User>(new ApplicationDbContext(new DbContextOptions<ApplicationDbContext>(), new HttpContextAccessor())), null, new PasswordHasher<User>(), null, null, null, null, null, null);
        var dbUser = userManager.FindByIdAsync(userId).Result;
        if (dbUser == null) return false;
        if (dbUser.RecordStatus == Domain.Entities.Enums.RecordStatus.Deleted) return false;
    
        return true;
    }