问题
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