0

Is there a way to put attributes for validation and for security in inner layers?
I want to put the security for example in the API layer.
The api layer is just an injected class to the controller.

the controller invoke the API.

api.Join(user);

class UserApi{
    //I want the attribute on a class library.
    [Authorized(Role....)]
    public void Join(User user){}
}

Thanks

SexyMF
  • 10,657
  • 33
  • 102
  • 206
  • You could do this by having an API layer invoker class that would check security according to method attributes and then execute method if everything's fine. Similar approach is used in MVC anyway. – Robert Koritnik Nov 22 '12 at 13:44
  • @RobertKoritnik, I dont understand you, can you please explain it a little bit deeper? maybe send an example? Thanks – SexyMF Nov 22 '12 at 13:46
  • Check what `System.Web.Mvc.ControllerActionInvoker` class does using Net Reflector, ILSpy or similar tool. Check how it invokes controller actions. – Robert Koritnik Nov 22 '12 at 13:56

2 Answers2

1

On the class library you can use PrincipalPermissionAttribute.

[PrincipalPermission(SecurityAction.Demand, Role = "...")]
public void Join(User user){}
Joe
  • 122,218
  • 32
  • 205
  • 338
  • Thanks, I am going to try it, what about validation attributes? – SexyMF Nov 22 '12 at 13:56
  • Validation attributes would be on your `User` class wouldn't they? And if your controller actions would use that as parameters, properties would get validated automatically by MVC. – Robert Koritnik Nov 22 '12 at 13:58
  • @Joe: But wouldn't this only work with windows authentication so forms auth won't cut it here? Because this attribute checks `Thread.CurrentPrincipal` and not `HttpContext.User`... – Robert Koritnik Nov 22 '12 at 14:02
  • if I want to do validation in the API, I need to use the ModelState, which is only existed on the web context – SexyMF Nov 22 '12 at 14:02
  • @RobertKoritnik - no, this is not restricted to Windows authentication. `Thread.CurrentPrincipal` needs to be set to the same principal as `HttpContext.User`, but if you're using a .NET RoleProvider this is done automatically. If you're not using `RoleProvider`, you may have to set `Thread.CurrentPrincipal` manually, e.g. in Application_AuthorizeRequest. – Joe Nov 22 '12 at 14:44
  • 1
    @SexyMF - you can manually validate using DataAnnotations attributes. For example, see the following blog post: http://odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx – Joe Nov 22 '12 at 14:47
  • @Joe: Ok. Then I will +1 your answer because then this is the **best solution** since it doesn't require any additional API Layer method invoker class. But regarding built-in Asp.net security model (and DB) I never uses it because I find it ridiculously superfluous. I've also never seen several apps sharing the same authentication/authorisation database (what they tried to do). It's true that I manly work on intranet apps so they usually use windows auth anyway. – Robert Koritnik Nov 22 '12 at 16:09
0

You'll want to look at Aspect Oriented Programming, for .net many people recommend using PostSharp

Community
  • 1
  • 1
dove
  • 20,469
  • 14
  • 82
  • 108
  • I thought about it, but I think this is really an overkill. .NET does not supports that put of the box? – SexyMF Nov 22 '12 at 13:51
  • 1
    @SexyMF: well you're trying to do something that's not provided out of the box by Asp.net MVC anyway... Authorisation filters are provided on controller actions and not on external classes. – Robert Koritnik Nov 22 '12 at 13:59