Is a centralized processing of request header data possible? - asp.net-core-webapi

Let me explain what my problem is:
In a Web API project I am facing the issue that every single request which is sent to my controller has to contain some header data which should be processed before the controller action runs.
So as far as I know, I could include a new argument on every single action and decorate it with a FromHeader Attribute. Currently there are about 2000 actions from several controllers where I would have to change the parameter signature. So it would be a much prettier solution, if I could centralize the processing of this header data.
I am looking for some code to overwrite which is between the constructor of the controller class and the execution of the controller's action. Does anybody know a method for overriding or a pattern to accomplish this requirement? May be there is a possibility to extend the routing to the action

public override void OnActionExecuting(ActionExecutingContext context)
{
/*
PUT YOUR CODE HERE ;-)
*/
base.OnActionExecuting(context);
}

Related

ASP.NET Web API - method that is called for all requests prior to the routed method?

I'm writing in C# for ASP.NET Web API 2. What I want is a catch-all method that will execute for every single request that comes to my Web API.
If the method returns null, then the original routing should continue, seeking out the correct method. However, if the method returns, say, an HTTPResponseMessage, the server should return that response and not proceed on to normal routing.
The use case would be the ability to handle various scenarios that may impact the entire API. For example: ban a single IP address, block (or whitelist) certain user agents, deal with API call counting (e.g. someone can only make X requests to any API method in Y minutes).
The only way I can imagine to do this right now is to literally include a method call in each and every new method I write for my API. For example,
[HttpGet]
public HttpResponseMessage myNewMethod()
{
// I want to avoid having to do this in every single method.
var check = methodThatEitherReturnsResponseOrNull(Request);
if (check != null) return (HttpResponseMessage)check;
// The method returned null so we go ahead with normal processing.
...
}
Is there some way to accomplish this in routing?
This is what Action Filters are for. These are Attributes that you can place either globally, at the class (Controller), or at the method (Action) levels. These attributes can do preprocessing where you execute some code before your action executes or post processing where you execute code after the action executes.
When using pre processing you have the option to return a result to the caller and not have your method (action) be fired at all. This is good for model validation, authorization checks, etc.
To register a filter globally edit the WebApiConfig.cs file.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new YourFilterAttribute()); // add record
// rest of code
}
}
To create a custom attribute inherit from System.Web.Http.Filters.ActionFilterAttribute or you can implement interface System.Web.Http.Filters.IActionFilter or you can implement IAuthorizationFilter/AuthorizationFilterAttribute if you specifically want to allow/deny a request.
It also sounds like you want to create multiple attributes, one for each role like IP filtering or count calling etc. That way it would be more modular instead of one enormous authorization filter.
There are many tutorials out there like this one (chosen at random in my Google search results). I am not going to post code because you did not do so either so I would just be guessing as to what you wanted to do.

Call another portlet from renderMapping

I want to call another portlet from renderMapping of one portlet. How can i do it. Code snippet is as follows:
Portlet 1:
#RenderMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response, Model model) {
if(!admin){
return "index"
}
else{
//i have to call the rendermapping method of Portlet 2 and need to redirect to portlet 2
}
}
How can i call the portlet 2 .
For maintainability reasons you shouldn't. If both use common code, extract it into a common implementation that both call into. That's the proper way of code reuse. If both portlets are in the same plugin, there will also be no classloading issue and this is a very easy option. Everything else (calling the render method of a totally different portlet) is not your business - leave it purely to the portlet container and don't go there yourself.
As far as I know, you can't. There's a reason why the portlet lifecycle has two phases, the ACTION and the RENDER phase.
If you want to redirect to another portlet, you'll have to use the action phase, so you'll need to create an action URL which can be clicked on, in the action phase you can do something like this:
#ActionMapping("goToDetail")
public void goToDetail(#RequestParam(value = "id") Long id, ActionRequest request, ActionResponse response){
response.setEvent("detailTask", id);
}
In this action phase we set an event, which triggers the portlet wires, so you'll have to configure those properly in your portlet.xml (supported publishing/processing events) and then you probably have to configure something on Liferay as well.

asp.net MVC : use unitOfWork inside custom AuthenticationAttribute when ActionFilters are not per-request?

I have implemented IAuthenticationFilter to create a custom one. in the constructor I use structureMap to get instance of my IUnitOfWork. this authentication logic is to check user status in the database and ....
IUnitOfWork uow;
public CustomAuthenticatationAttribute()
{
this.uow = ObjectFactory.GetInstance<IUnitOfWork>();
}
I have configured structureMap to serve IUnitOfWork HttpContextScoped.
x.For<IUnitOfWork>().HttpContextScoped().Use(() => new MyDbContext());
but then something strange happened. I deleted the user in one action, but when the AuthenticationFilter is executed on another action, the instance of unitOfWork still returns the user ! I searched the web for hours and I come to this :
Are ActionFilterAttributes reused across threads? How does that work?
in short , it says that Filters are cached and used across requests !
Now I'm confused . how to deal with this ? shall I give up using unitOfWork and get back to using(var context = ....) ? or there is a correct way of using unitOfWork inside Filters .
I found a solution here
https://gist.github.com/ivanra/9019273
It replaces the DefaultFilterProvider and I prefer to avoid that if possible.
The solution you found with suppressing caching in the FilterProvider is actually the same solution that the MVC integration libraries for both Autofac and Simple Injector use.
But the caching behavior of attributes is just one of the many reasons why doing dependency injection in attributes is actually a bad idea.
The best solution is IMO to move to passive attributes if you can, or at least encapsulate the attributes logic and its dependencies into a component and don't do anything more than resolving and executing that component in the OnActionExecuting method. For instance:
public class CustomAuthenticatationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var action =
ObjectFactory.GetInstance<IActionFilter<CustomAuthenticatationAttribute>>();
action.OnActionExecuting(this, context);
}
}

Custom authorization in ASP.NET as filter or in controller's constructor?

In my ASP.NET Web API controller, I want to restrict access to those in the User role. The common way to do this is to extend the AuthorizeAttribute (example, example) and then sprinkle my controllers with my custom attribute (e.g. [AuthorizeUser]).
Another way to do this is to add a function in the controller's constructor. The constructor is required anyway because I'm using dependency injection.
Here's some code:
public class MyController: ApiController
{
private IUnitOfWork unitOfWork;
private IAccountUtils accountUtils;
// Constructor
public MyController(
IUnitOfWork unitOfWork,
IAccountUtils accountUtils)
{
this.unitOfWork = unitOfWork;
this.accountUtils = accountUtils;
// Restrict access to 'User' role
accountUtils.ThrowExceptionIfUserNotInRole(User.Identity, "User");
}
// More code
}
Because there are countless tutorial and examples of using a filter to authorize users I assumed that was the best way to go. However, when I stepped through my code in the debugger I found that the constructor method gets fired BEFORE the filter.
To optimize code, it makes sense to break as soon as possible if the user is not authorized to access the controller. If I'm not mistaken, then, it should be more efficient to perform authorization in the constructors instead of in a filter. Am I correct or am I missing something here?
It seems like your main concern is optimizing your code, and you're correct to note that the controller constructor runs before the authorization filter. But the difference in performance between those two solutions is extremely small and shouldn't really impact your service.
While throwing from a constructor might work, it's not the most elegant solution because it requires you to authorize in code rather than declaratively with an attribute. It also forces you to mix object instantiation logic with authorization logic which isn't as clean.
So I'd recommend just sticking to using an authorization filter for this one.

Find out the name of the controller and action before the request is serviced

I want to intercept every request coming into my MVC app after the ControllerName and Action have been resolved, but before the request is serviced, i.e. before it reaches the appropriate action.
I have thought of two ways of doing this:
1) I could write an HttpModule to intercept every incoming HttpRequest, read the HttpContext.Request.AbsoluteUrl (or some such) property, then assume that the route I have configured will never be changed (and that is the assumption I want to avoid or I would have gone this way), and infer the names of the controller and action that are being invoked.
However, I am looking for a more reliable way. Hence (2) below.
2) I assume that MVC already does this for me at one time or another before instantiating the right controller. I want to know where it does that so I may be able to re-use its work. At which point may I get this information, intercept the request and do something about it before it reaches the action?
You could create a global action filter where you will have access to the controller and action:
public class MyGlobalActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string controller = filterContext.RouteData.GetRequiredString("controller");
string action = filterContext.RouteData.GetRequiredString("action");
// do something with those variables ...
}
}
The OnActionExecuting method will be invoked before every controller action is ran and you will be able to retrieve the information you are looking for from the RouteData.
And then simply register your global action filter in your Application_Start:
GlobalFilters.Filters.Add(new MyGlobalActionFilter());

Resources