views:

2824

answers:

4

Hi,

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

A: 

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.

Craig Stuntz
If I put authorization logic in my REST APIs, then I will have to duplicate it in the controllers too. Thats why I need to do something which is in service layer (not WCF, just c# class library)
Ajay
You don't have to duplicate anything. WCF and ASP.NET will both tell you *who* is connected. You simply have to translate this into *what* they can do. This code could be shared. You just shouldn't do it with a custom attribute is all I'm saying. Use what's already built-in to the frameworks.
Craig Stuntz
What if he decides to add another front end? He would have to write all those attributes once again.What if he changes some rules, like what groups are allowed to call a method? He would have to change all of his frontends.There is possibility to create such an attribute (with aop), and I believe that Ajay should do it, because only that way he can ensure that authorization is consistent for all fronteds and that he can safely add another frontend and don't care about all that authorization stuff that is common to all frontends...
maciejkow
maciejkow: I did not suggest using attributes. I suggested using built-in identity management with shared identity->rights code. If you think I suggested writing anything more than once, please reread what I wrote.
Craig Stuntz
A: 

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.

Keith
in ASP.Net MVC I can do this, I need to do the same in C# class library, so that any one who is calling c# method, it should do the authorization checking. Thanks.
Ajay
+5  A: 

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.

maciejkow
thanks a lot. postsharp is looking good. I am digging in to it right now. Hopefully my architecture will get a good boost.
Ajay
+1  A: 

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.

Wyatt Barnett