如何在 .net core 1.1 中访问操作方法之前在控制器属性上设置用户?



Using .net core 1.1 mvc

目的是限制用户,以便他们只能编辑自己,或允许管理员编辑用户。我需要获取当前用户并将该用户的 id 与在参数(或 cookie(中传递的用户 ID 进行比较。

如果用户 ID 不匹配,请检查当前用户是否为管理员。如果是这样,请获取作为参数(或 cookie(传入的用户 ID 的用户。

我们有一个控制器,它通过依赖注入在构造函数中接收ApplicationDBContext和UserManager。

我两次尝试都失败了: 1(我尝试创建一个通过上下文访问用户管理器的动作过滤器。Controller.UserManager(我从控制器构造函数设置的属性(,但UserManager有一个IDisposable错误。

2( 我尝试从控制器构造函数执行此操作,但是如果未找到用户并且不知道如何从 Action 方法外部执行此操作,则需要将响应设置为 404。

经过一天的反复试验,我想通了,想分享,因为我在网上找不到任何例子。

请注意,我必须使用 IAsyncActionFilter,因为只要我在筛选器中调用异步方法(Controller.UserToEditProp = await UserManager.FindByIdAsync(,代码就会在 Action 方法中开始执行。

public class ImpersonateAttribute : ActionFilterAttribute, IAsyncActionFilter
{
    public override async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next)
    {
        string ThisUserID = context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
        ApiController Controller = (ApiController)context.Controller;
        var UserManager = Controller.UserManager;
        if (context.ActionArguments.ContainsKey("UserID"))
        {
            string RequestedUserID = context.ActionArguments["UserID"].ToString();
            if (ThisUserID != RequestedUserID)
            {
                if (!context.HttpContext.User.IsInRole(UserType.Admin.GetDisplayName()))
                {
                    context.Result = new UnauthorizedResult();
                }
            }
            Controller.UserToEditProp = await UserManager.FindByIdAsync(RequestedUserID);
        }
        else
        {
            Controller.UserToEditProp = await UserManager.FindByIdAsync(ThisUserID);
        }
        await next();
        // do something after the action executes
    }
}

最新更新