Authorization & User info in a Service Layer (.NET

2020-02-28 05:31发布

问题:

I am currently working with an enterprise application in a .NET environment (n-layered) and I would like to know the best way to manage authentication / authorization + data filtering in my BussinessLayer (BL). We will use that BL from several interfaces (ASP.NET applications and WebServices) and I think that my ServiceLayer should do the job but I just can't find the best way.

I suppose it could be something like this: (1) User gets authenticated (ASP.NET web client), perhaps using FormsAuthentication. (2) ASP .NET code (Controller / CodeBehind) instanciate a Service to get some user case done, passing somehow the 'User'. (3) Service method checks if 'User' exists (authentication) and his roles (authorization) to verify that he can call that method. If not authenticated or authorized an exception is thrown. (4) Service uses repositories + other services + whatever it needs to get the job done. If some kind of fine-grain filtering is required (for example the User only has permissions over some projects) the service applies it automatically.

What I want is to get a ServiceLayer isolated from 'the web stuff' (not accesing session...) but who knows the User calling its methods to act correctly. Also I don't know how to match that work with ASP .NET authentication in a good manner... I am thinking in suministrating the 'User' in the Service ctor, so that its methods have the 'context' they need, could that work?... I would appreciate some indications or existing code snippets on that.

Thank you for your help...

回答1:

First of all, Authentication and Authorization are two separate things. Your question implies that you already know this, but I just wanted to be explicit about it.

Authentication should happen at the application boundary (e.g. Forms Authentication in a web application).

The default approach is that the Authentication module sets Thread.CurrentPrincipal upon successful authentication.

In general, IPrincipal is the standard basis for modeling user context in .NET. For example, HttpContext.User is an IPrincipal.

In your Domain Model and Data Access modules, you can use Thread.CurrentPrincipal to implement Authorization logic. This allows you to vary Authentication and Authorization independently of each other.



回答2:

For me, I think it is both simpler, and more extensible if you let the client layers (your website/services) do the authentication and leave the BL to contain just the business logic.

If you need a reference to the current user in the BL, you could consider an interface to 'wrap' some of the user identity information and this could be passed from the various UI layers.