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;
    }
1

There are 1 best solutions below

1
Nathan On BEST ANSWER

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;
}