Writing Custom Attribute in C# like ASP.Net MVC Authorize attribute - c#

I like ASP.Net MVC Authorize attribute, I can extend it and build my own logic and decorate my controller with it. BUT,
In my architecture, I have one common service layer(C# Class Library). End user can access my application via ASP.Net MVC web site or via my exposed REST WCF Webservice layer.
My asp.net MVC application and REST WCF service layer both in turn access my common service layer.
I want authorization to happen in this common service layer and not in ASP.Net MVC Controller or in my exposed REST Service layer.
Can I create ASP.Net MVC Authorize attribute like thing to decorate my methods in the common C# class library? This attribute will take parameters and will decide if the current user has access to perform that function or not?
Thanks & Regards,
Ajay

What you're looking for can be achieved using AOP library, like PostSharp (http://www.postsharp.org/). It's more complex than using Authorize attribute in mvc, but is still quite simple.

Another way to handle this is to use the [PrincipalPermission] attribute in your service layer. This can prevent callers from executing a method (or accessing an entire class) without the defined authorization.

No, AuthorizeAttribute works because the MVC framework explicitly invokes it before calling the method. A similar feature for your service layer would only work if your clients explicitly invoked it, as well. It would not be reasonable to presume that even a well-intentioned client would always remember to look for the attribute and invoke it. WCF has its own security. You should use that instead of writing your own.

This shouldn't be too hard to do - there are a couple of places that you could reflect out the attribute and handle it accordingly:
On application start in Global.asx you can customise routing and locations for views
Underlying ASP.Net request events still fire, so you could override one of them
Create your own base controller and override OnActionExecuting
Update following comment
Ahh, I see. In that case if you're making direct calls then you should check out Code Access Security, which I think covers what you mean.
Alternatively a custom attribute might make sense as long as you are using some kind of factory pattern - then the reflection call that gets the factory could check the attributes.
If you're not using reflection to retrieve your classes or call your methods (which is essentially what routing does in MVC) then you won't get the chance to check your attributes.

Related

Authorization/Authentication in asp.net web api

I need to create a couple of simple methods using asp.net web api. I am very new to this so even the simplest thing is proving difficult for me. I want to decorate my api controller with [authorize] and [authenticate] for the obvious reasons.
My question is centred on how I call these methods from my ajax calls (which is how I'm intending to call them). I'm reading that I need to pass the user id and password with each of my calls but how do I do this using ajax? Or do I even need to do this manually or asp.net somehow does it for me (if that even makes any sense)? Because when I'm doing action calls that need to be authenticated/authorized using forms in mvc, I certainly don't do it expressly and I imagine somehow somewhere in the code it just gets done.
As is clear, I'm very lost. Any help is appreciated.

Autofac - Decorate all components from a particular assembly

So I want to do some profiling on a bunch of controllers which inherit from System.Web.Http.ApiController. In the project that's doing the profiling, we're registering them with
builder.RegisterApiControllers(typeof(Web.Modules.AutofacModule).Assembly)
.As(type => new Autofac.Core.KeyedService("api", type));
Later on, I'm trying to register a decorator for each with
builder.RegisterDecorator<ApiController>(original => Decorate(original, profiler),
fromKey: "api");
where Decorate injects some profiling code via a DelegatingHandler and returns the original.
I can resolve the controllers just fine:
scope.ResolveKeyed<RegistrationController>("api");
but the profiling code is never invoked, nor is Decorate.
My first thought was that maybe I need to register the controller components as ApiController's, but dropping an .As<ApiController>() just below first snippet wasn't successful.
Any help would be super. This probably just boils down to my lack of Autofac-fu.
So I want to do some profiling on a bunch of controllers which inherit from System.Web.Http.ApiController.
This is impossible. This has nothing to do with Autofac, but with the way ASP.NET Web API is designed.
Even though Web API Controllers derive from a common base class, ASP.NET Web API requires the original controller type to be used. In other words, when it requests a HomeController from the IHttpControllerActivator, it expects that exact type (or a sub type), but not a sibling type (another ApiController derivative).
I think this limitation exists because Web API uses reflection to find the actual action methods. But when you return a decorator, those methods are gone, because a decorator applies composition instead of inheritance. This is very different from how ASP.NET MVC is designed. MVC actually does allow controllers to be decorated, as it always invokes the IController.Execute method. Implementation IController is therefore MVC's only requirement for controllers.
So even if you configure Autofac to wrap any ApiController derivatives in a Decorator, Web API simply won't let you.
The way to apply Cross-Cutting Concerns around the invocation of action methods in Web API is through the use of delegating handlers.

ASP.NET Web API 2.0 pipeline and ASP.NET Core Web API pipeline differences

I recently started migrating my app from Web.Api .NET standard to .Net Core.
First of all are all the steps of the Web Api pipeline still there?
When i say all the steps i mean :
Web api pipeline Poster
In terms of usage i can see the filters are applied through the
[ServiceFilter(typeof(NameOfAttribute))]
But in a variety of articles like this one :
https://andrewlock.net/asp-net-core-in-action-filters/
i can see different kind of filters like resource and results filters.
Also i cannot see the usage of Delegating Handlers.
Where should we integrate the functionality of the previous pipeline with the new standards?
Thanks
Since classic Asp.Net and Asp.Net core are cognate technologies there are many common concepts in a request processing, but there are some differences and most likely you will have to rewrite some stuff in your project.
As you noted there are new filters. They allow to handle request in more granular approach. You can use filters as you did it before just by decorating actions and controllers:
[SomeFilter]
public IActionResult SomeAction(){...}
And (as before in classic Asp.Net) you can't use dependency injection through the filter constructor. Filters applied like that behave like a singleton. One instance is used for all requests.
ServiceFilterAttribute and TypeFilterAttribute allow to use the dependency injection through the filter constructor. Optionally filters applied like that can behave like singletons or can be created every time (with dependency injection) for every request. You can adjust it by using IsReusable property. Read more about filter here.
There are no more Delegating Handlers. Instead of you can create a custom middleware. You can see an example here.

Using HttpApplicationState outside ASP.NET session

I have following problem. I am trying to use web services wrote in ASP.NET in application as intermediate layer, stored inside WCF service layer. So I am instancing some WebService classes and I call web methods like normal C# methods.
Unfortunately some of them are using asp.net specific solutions like using HttpContext and Application object(of type HttpApplicationState). I am trying to add items to this collection before webservice call, but nothing happens! Items are not there after using Add method. No exception, nothing. I thought that there is some functionality inside implemenatation of HttpApplicationState class, that prevents this operation in certain cases, but I insepcted code in reflector and everything should be fine...
Am I missing something?
Not positive I understand your application structure, but it sounds like you want to run wcf with asp.net compatibility turned on to allow HttpContext?
http://msdn.microsoft.com/en-us/library/aa702682.aspx

Change the Location of the Controller inside the Project structure

I found this Post (How to extend where MVC looks for views) about changing the location of the View.
I was wondering if there's something similar for changing the location of the controller.
I just want to change the location of the class inside project and don't want to affect the url.
For example Instead of placing the Controller into
MyMvcProject\Controllers\
MyController1.cs
MyController2.cs
MyController3.cs
I want to achieve something like
MyMvcProject\MyGroup1\
MyController1.cs
MyController2.cs
MyMvcProject\MyGroup2\
MyController3.cs
and also support Areas:
MyMvcProject\Areas\MyGroup3\
MyController4.cs
Is it possible to achieve this? And if yes, where can I find documentation about it?
You can do what you want, and it doesn't require any special configuration, because ASP.NET MVC does not care about where you put your controllers. First, controllers are located using reflection, so the name of the folder where you put your controllers is irrelevant. Controllers are searched by type name and optionally by namespace (for disambiguation). You can even have controllers in separate projects/assemblies. As long as the controller ends up in an assembly in the bin folder then it's searchable by the framework.
As mentioned above, you'll need to create a controller factory to support your custom resolution. Here's an example:
http://develoq.net/2010/custom-controller-factory-in-asp-net-mvc/
As others have already stated you need to do one of the following:
Derive from IControllerFactory interface and provide an implementation of the CreateController and ReleaseController methods.
Derive from DefaultControllerFactory and override the default behaviours.
Here are some links to get you started:
Custom controller factory in ASP.Net
Inside the ASP.NET MVC Controller factory
Dive deep into MVC - IControllerFactory
Also, if you're willing to spend a bit of money I would also recommend the book Pro ASP.NET MVC 3 Framework as this explains almost every aspect of how the MVC framework can be customised (including an example on how to create a custom controller factory - the source code for which can be freely downloaded from the publishers website).
I think it is impossible to do this. ASP.NET MVC have defined the convention that we have to follow.
Controllers are in Controllers folder, views are in Views{ControllerName}\
I believe you cannot change the convention unless you create your own ControllerFactory.
If you really want to do that, just implement IControllerFactory interface (or try to derive from DefaultControllerFactory).
Then your Application_Start register your controller factory using ControllerBuilder.Current.SetControllerFactory method.
Look at the ControllerFactory documentation and to the MVC source code for details.
What you're asking and what your example shows are two different things; depending on which one you want to achieve, you may or may not need to do any work.
There are two requirements for a class to be a controller in the MVC Framework:
It has to have a class name of Name + "Controller"
It has to have a parameterless public constructor.
Your sample "normal" MVC layout is actually not valid:
MyMvcProject\Controllers\
MyController1.cs
MyController2.cs
MyController3.cs
Those classes wouldn't be found by MVC because they don't have the correct name, regardless of which folder they are in.
If all you want to do is change the namespace/folder names, that "just works", assuming you name them the same as the appropriate route segment(s):
MyMvcProject\MyGroup1\
Page1Controller.cs
Page2Controller.cs
MyMvcProject\MyGroup2\
Page3Controller.cs
MyMvcProject\Areas\Area1\
Area1Page1Controller.cs
This walkthrough (written for MVC 2 but works just as well in MVC3) shows you how to support Areas with the default controller behavior.
If you actually want to name them SomethingController1 or SomethingElseController5, or otherwise change the route -> classname mappings, then you do need to implement a custom ControllerFactory, and inject it into the MVC pipeline.
There are plenty of examples on the web on how to do this, including the one posted earlier.

Categories

Resources