Get the api controllers constructor value within an AuthorizeFilter

拜拜、爱过 提交于 2019-12-06 14:46:50

问题


When the user is authenticated I want to prevent that he updates/deletes/reads data created from other accounts... by telling him you do not have the permission 403!

What is the best way to get an instance of the ISchoolyearService to invoke its HasUserPermission() method?

I know I could new up the SchoolyearService here but that would defeat the reason using an IoContainer at all in my app.

public class UserActionsSchoolyearAuthorizationFilter : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext != null)
        {
            bool canUserExecuteAction = false;
            if (actionContext.Request.Method == HttpMethod.Put)
            {
                int schoolyearId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
                int userId = actionContext.Request.Content.ReadAsAsync<SchoolyearEditRequest>().Result.Schoolyear.UserId;
                //var schoolyearService = actionContext.ControllerContext.Controller.GetContstructorParameterServiceInstance();
                //canUserExecuteAction = schoolyearService.HasUserPermission(userId, schoolyearId);
                if (canUserExecuteAction)
                {
                    base.OnAuthorization(actionContext);
                }
                else
                {
                    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
                }

            }
            // Removed for brevity

    private readonly ISchoolyearService _service;
            public SchoolyearController(ISchoolyearService service)
            {
                _service = service;
            }

回答1:


If you made the _service parameter public on your SchoolyearController you could try something like this in the OnAuthorization method:

var schoolyearController = actionContext.ControllerContext.Controller as SchoolyearController;
canUserExecuteAction = schoolyearController._service.HasUserPermission(userId, schoolyearId);



回答2:


Ok finally I found it out how to get the ISchoolyearService from the current request:

Grab the registered service from the DependencyScope!

Now this Attribute should be put on the controller directly. Its not needed to put it on the action due to the if/else on the http verbs which I do.

bool canUserExecuteAction = false;
if (actionContext.Request.Method == HttpMethod.Put)
{
    int targetId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
    int userId = actionContext.Request.Content.ReadAsAsync<SchoolyearEditRequest>().Result.Schoolyear.UserId;
    var requstScope = actionContext.ControllerContext.Request.GetDependencyScope();
    var service = requstScope.GetService(typeof(ISchoolyearService)) as ISchoolyearService;
    canUserExecuteAction = service.HasUserPermission(userId, targetId);

    if (canUserExecuteAction)
    {
        base.OnAuthorization(actionContext); 
    }
    else
    {
        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
    }
}


来源:https://stackoverflow.com/questions/21173880/get-the-api-controllers-constructor-value-within-an-authorizefilter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!