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...
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.
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.
Related
Since IdentityServer's object is to provide authentication and authorization via implementing OIDC and OAuth2 it makes sense to me that user management (CRUD operations) is done separately, maybe in it's own assembly (these seem like two different concerns).
In a production scenario how do you go about separating these two concerns? I see two general options here:
There is a separate identity proverider (ASP.NET Identity Core) project/solution that exposes an API to create, update and delete user entities within its storage. IdentityServer calls this API when authenticating a user.
The user CRUD action endpoints reside within IdentityServer's host project. IdentityServer has direct access to the DbContext of the identity provider's database and implements all necessary user management operations.
The second approach is obviously the easier to implement, but I think that could mean uneccesary redeployments of the auth server if there are functionality changes regarding to the CRUD user operations.
Also what about functionality like forgotten password, email validation and so on. Where is the proper place for it? With IdentityServer or with the separate IdentityProvider (and IdentityServer calling its API).
I've seen a couple of StackOverflow questions in regard to this, but nowhere could I find a sound sample or good reasoning, everything was vaguely described.
P.S The IdentityProvider will be ASP.NET Identity Core
I am investigating how IdentityServer 3 works and I still have problem to fully understand.
In general concept is clear to me but still I am not sure how to implement this on real project.
This is basic example that I am trying to implement in my case: link
I have web api project and I want to call my api methods from any client (mvc, wpf, phone…)
So I need implementation that is suitable for all clients.
If I understand well (and probably I am not understand completely), I should have 3 projects:
Client
Api
Project that host IdentityServer
And all projects should have required stuff like on picture:
Steps on picture:
Get token
Return token
Call api
Check if Token is OK
If Token is fine than return data else show error
My questions are:
Is my thinking about how this works ok?
Where I making mistakes?
Is this example good enough for my case? Am I missing something
important?
Do I have to create project that host IdentityServer, or this is
needed just for example code ?
Does IdentityServer host project must be console application that
communicate with api and client(like in example), or in real world
this is done differently ?
Should project that host identity server be aware of Clients and
Users ?
Should some other project except host identity server project be aware of Clients and Users ?
What is diference between implicit and hybrid flow, what I need in my case and why?
How do I create my own login view? I want have html page for login if I use web client, but to have wpf login view if I use wpf, also different view for mobile client.
EDIT:
I think that I need Resource Owner flow . I supose that resource i view where user type user name and password.
Your basic flow is correct, with Identity Server acting as your authorization server and your client and web API separate.
You should host Identity Server in its own project to ensure it is separate from any other logic which has the potential to introduce security concerns. How you host it is up to you and your use case. Typically you would see it hosted within an ASP.NET project on an IIS Server.
Identity Server must be aware of clients and users in order to authenticate them. The only other projects that should be aware of your identity store (users) is any applications that concern things like admin, user registration, etc. The client store would only ever be used by Identity Server.
Views can be modified using the Identity Server templates or by introducing your own ViewService. See the docs for more info: https://identityserver.github.io/Documentation/docsv2/advanced/customizingViews.html
Regarding flows, the Resource Owner flow is OAuth only, so there will be no authentication (log in page), only authorization (server to server).
My task is to put an authorization policy to existing / legacy wcf services. Currently there is no authorization in the system. Basichttp based custom binding is being used to handle security. ( The client is sending username / pwd in encrypted form and on the server side, database check is performed upon receiving request. At this point an expirable token is generated in and put to server memory for further security checks) Moral of the story, everything is implemented in a custom way (security features of the framework like STS, certificates and etc. are not utilized) In the service layer no authentication check is done according to client identity. Theoretically, every client can perform every operation as long as he /she has a valid username / pwd pair.
As I said, my task is to implement an authorization policy on this legacy system.
I am relatively new to wcf and my feeling is that authentication and authorization is VERY TIGHTLY COUPLED in wcf.
It seems that there are various alternatives ( http://msdn.microsoft.com/en-us/library/ff648151.aspx ) like :
*Using the ASP.NET Role Manager for role authorization,
*using the SQL Server role provider for role authorization,
and etc.
I feel that custom authorization policy would be the most suitable alternative for me but the custom samples
http://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx also seem to be mixing authentication policy with authorization policy. I could not find a working good sample that implements a custom authorization without any special authentication policy. As you can guess, in the current legacy system security is handled in a custom way and I can not change that i.e I can not use any ws-* bindings.
What I am thinking as a possible solution is:
1) Create a custom attribute that implements ParameterInspector or MessageInspector
2) Decorate all the existing operationcontracts with this new custom attribute
3) In BeforeCall or AfterReceiveRequest methods, apply the custom authentication logic (This custom logic will most likely be associate users with roles and roles with allowed operations).
Rejecting the request will be by throwing an exception and showing the message appropriately in the client side.
My question is, how elegant is this approach? Considering the other restrictions of the legacy system are there more elegant alternatives? Am I missing some parts or are authentication and authorization really very tightly coupled in wcf?
In the old days, basically you could use declarative programming to decorate each operation implementation with PrincipalPermissionAttribute with role name, then in Web.config you plugin ASP.NET MembershipProvider and RoleProvider etc. And if you want more fine grained policy control, you could write a few IAuthorizationPolicy implementations, as you had already found our in those MSDN references in your question.
So you expect more elegant alternatives, even if your purposed designs might be working. Being elegant:
Adequate security
Least codes
Least complexity in application
Easy to evolve
This article "Authentication and Authorization with ASP.NET Identity 2.0 for WCF Services" might give you some light.
And there exists many articles about the reasons why using Identity 2.0.
I would use an external authorization framework altogether and then apply a MessageInspector. The externalized authorization architecture would be as follows:
Externalized authorization management is about decoupling your business logic from your authorization logic. It's great when building new apps efficiently and it's great when updating legacy apps - especially web services where you can easily intercept a flow. Have a look at Gartner's report on externalized authorization.
For your problem more at hand, I recommend you use XACML, the eXtensible Access Control Markup Language. It's an OASIS standard that provides you with:
a policy language to define policy-based access control authorization
a flexible architecture with the notions of:
a policy enforcement point or PEP which intercepts your flow and protects your WCF services. In your case you should use a PEP that implements a MessageInspector
a policy decision point or PDP which receives the requests from the PEP and produces decisions based on the policies it is configured with.
a request/response scheme which defines how the PEP and PDP talk together.
Here's a diagram that sketches out the way you would want your system:
If you need a .NET PDP, you can get one from Axiomatics (disclaimer: this is the company I work for).
HTH
I need to be able to tighten my business layer - access to particular data.
The UI can make a call to the business layer and receive a userdetail. The UI can then call .Save() on a user and the business layer will call the data access layer to save the user.
Although, the problem here is that I don't just want any user to be able to receive a userdetail and call save - only authenticated users with that role of "admin". How would I go about this authentication/authorisation in my business layer/UI so I can achieve this?
I am using ASP.NET for my UI, and I've read into membership/role providers, but this just seems to be for the actual UI. I need to secure it at my business layer because in the future there could be a couple of different UI's. e.g. windows forms and Asp.net.
Thoughts and suggestions are appreciated.
Thanks.
Another approach you might want to research (if developing in .NET 3.5 / 4.0) is using Windows Identity Foundation.
If you are insterested in keeping your authorization logic outside your web site (which I assume you would if you are expecting to use your business layer from more than 1 front-end) I would definitely recommend yaking a look at WIF. You can also integrate with Active Directory using ADFS v2.0 (which is a server role in Windows Server 2008 R2).
Patterns & Practices has released a guide which can be quite useful for digging into the subject.
The ASP.NET Role / Membership providers include storage and code level components you can re-use - they aren't just the UI.
For fine-grained access control (for example to specific functionality on a page) you can use the Enterprise Libraries. You'll be able to re-use code to protect functionality both at the BL layer and in the UI layer.
The link you most want is this one: Determining Whether a User Is Authorized to Perform a Task
Also see:
What Does the Security Application Block Do?
DotNetJohn - Enterprise Library Security Block...
Rule Based Security using Microsoft Enterprise Library and CAS
During earlier releases of the EntLibs, the Authorization Manager was a key component, but in more recent versions it's not a firm requirement, instead you can use an AuthorizationRuleProvider.
see: Developing Applications Using Windows Authorization Manager.
Filtering data is a bit more problematic depending on the complexity of your data, the amount of it and performance needs.
One strategy is to have a simple DAL that returns everything, and prune out data the current user isn't allowed to see in the BL.
Design a DAL that has some knowlegde of the roles your application uses:
DAL.GetCustomersForAdmin() and DAL.GetCustomersForMember() But this is a bit dangerous as you'll be tied to using those roles.
Have a database / DAL that is security aware, and always returns only the data the user is permitted to see, via the same methods: DAL.GetCustomers()
I am relatively new to the WCF world so my applogies for the newbie question. I am currently designing a layer of WCF services. One of them is an authentication service, so I came up with the following authentication mechanism:
IUserService.TryAuthenticateUser(string username, string password, out string key)
Basicly the user tries to authenticate and if successful - he/she receives a sessionkey/securitykey/whateverkey... the key is then required for every other "WCF action" e.g.
IService.GiveMeMyFeatures(string key);
IService.Method1(string key);
This mechanism looks extremely intuitive for me and is also very easy to implement, so what bothers me is why I cant find similar WCF examples? This unique key (which is practically a session key with wcf-side expiration and all) can then by used from the various applications, according to the application's architecture: for ASP.NEt it can be stored in a cookie, for Winform/WPF/Mobile I guess it can be stored in the form-class in a field and so on...
So here comes question number 1: What do you think of this method?
I also read, that I can use the build-in ASP.NET Authentication Services (with membership providers etc... if I understood correctly). From architecture point of view I dont really like this method, because when authenticating from an ASP.NET page the workflow will be like this:
ASP.NET -> WCF -> ASP.NET Authentication Service -> Response
In this scenario one could also bypass the WCF layer and call the auth. service methods directly from the asp.net page. I know that by going thru the WCF layer for every authentication request I will lose some performance, but it is important for me to have a nice, layered architecture...
And here is question number 2: What are the advantages/disadvantages of this method over the first one, and why is it so popular, when from architecture point of view it is kinda wrong?
I also read, that I can send user credentials for every WCF method call and use the built-in mechanism to authenticate and respond properly to the request.
Q3: What do you think if this method?
And to sum up - obviously there are many authentication methods, but which one do you think is best and most generic (considering that the WCF services will be called from asp.net/wpf/mobile/etc...)?
Thanks is advance :)
The reason you can't find examples it's not best practice - it's turning something that should be stateless, web services, into something stateful, and something that will not load balance well at all.
As web services already have standard username and password facilities, supported by almost every SOAP stack (excluding Silverlight) that's the way to go. You can use the standard .NET role based security model to protect your methods with this approach as well.