Exposing existing Service Layer using ASP.NET WebApi - c#

I currently have a layered architecture that is as follows:
Service Layer - This is the main interaction point with the domain.
Contains all the business rules, validation, etc.
Data/Repository Layer - This is the layer that handles all persistence of the data. Contains no business logic or validation. Contains basically Repository<T>, UnitOfWork (EF Specific) and all the EF things like DbContext, EntityTypeConfiguration's, etc.
Entity Framework
SQL Server
I am using an Anemic Domain Model, so basic POCO's that represent the problem domain.
I have a couple questions about exposing this via ASP.NET WebApi.
Where does the security live at? Basically things like does a user have the access to edit a record, or type of record. Can a user perform a specific action, etc. As well as things like Authentication/Role Based Authorization.
Should I use the WebApi as the actual service layer, or use it to expose my existing service layer over HTTP in a RESTful manner?
Given a basic example of say changing a name of a category, where do I enforce that the current user has authority to change said record? Do I rely on the Thread.CurrentPrincipal to get the Identity to check for a given role, and set that in the WebApi? Mvc Application?
Are there any good examples out there that show this type of situation I am talking about?
BTW - I am using ASP.NET MVC 5 to serve up the shell of the application (SPA) and then the front-end is going to be all AngularJS.

Regarding your first question about the level of security your services should have the correct answer is what I believe it should be a principle in all applications:
Services should have enough security to protect the data from unwanted users.
Once you create a service and make it public you are exposed to possible attacks of course having complex security rules may increase development time and some situations may create a decrease in performance; measure the level of the threat and plan your security accordingly.
WebApi was created with intention to provide services through Http/Rest all the principles and features build-in were made with that intention so regarding your second question and like you inferred at the end of it it is a service layer but an Http/Rest service layer.
WebApi uses an attribute Authorize to enforce security an as it is normally with .NET Frameworks you can inherit from it and extend it. You can learn more about it here.
And since you are using Angularjs and even though you will need MVC5 to use WebApi my recommendation is that you do not use MVC razor or any other server technology to render your pages.

Related

In a layered architecture, how can the Application layer know about Web URLs?

I'm currently working on a .NET 5 app that is using a layered architecture (Web / Application / Infrastructure / Domain). If I am to follow the onion/clean architecture pattern, the dependencies should flow in one direction only, e.g:
Web -> Application -> Infrastructure -> Domain
I now find myself needing to send several emails from the Application layer containing specific front-end URLs. This means that the Application layer will know about the Web layer, breaking the dependency flow.
A sample use case flow would be:
User makes a request, gets handled by a controller in the Web layer
Controller calls a handler on the Application layer
The Application layer uses an email service from the Infrastructure layer to send an email
On step #3 I'm in the Application layer but need Web URLs to construct the email body.
How can I solve for this issue?
I've recently solved this problem within my organization. In our case we have an API "market place" used by the company as a whole, then a reverse proxy used by closely integrated clients, and finally an internal load balancer for the API containers.
That's 3 layers of URL knowledge that my Web and App layers shouldn't know about (even at the Web layer it shouldn't know this because that would make our web layer have more than one responsibility rather than just be a router (e.g. via Mediatr)).
Using Rewriters in the Infrastructure
This is what Z. Danev's answer is all about. This works, but you must maintain all the rules for each of these layers, and each of those rewrites may add overhead. Also, those rules could get tricky depending on the complexity of the data you return.
It is a valid solution though. Depending on your organization this may be an easy thing, or it may be a hard one because it's maintained by other teams, need work tickets, and so on to get the job done.
Well, if you can't or don't want to do that, then...
Application Layer Dependency Inversion and Patterns
Disclaimer: This solution works great for us, but it does have one drawback: at some level, you have to maintain something that knows about the layers above. So caveat emptor.
The situation I described above is roughly analogous to your problem, though perhaps more complex (you can do the same but simplify it). Without violating your architectural principals you need to provide an interface (or more than one) that can be injected into your application layer as an application service.
We called ours ILinkBuilderService and created a LinkBuilderService that itself can be wired up through a DI container with individual ILinkBuilder implementations. Each of these implementations could be a MarketPlaceBuilder, a GatewayBuilder, etc. and will be arranged according to a Chain of Responsibility and Strategy patterns from outermost proxy to innermost.
In this way, the builders inspect the web context (headers, request, etc.) to determine which one should handle the responsibility of building links. Your application layer (e.g. your email sender) simply calls the link building service interface with key data, and this is used to generate client-facing URLs without exposing the application layer to the web context.
Without going into too many details, these builders inspect headers like X-Forwarded-For, custom headers, and other details provided by proxies as the HTTP request hits each endpoint. Chain of Responsibility is key, because it allows the application layer to generate the correct URL no matter at which layer the request originated from.
So how does this not break the one-way flow?
Well, you push these builders one-way down into your application layer. Technically, they do reach back up to the web layer for context, but that is encapsulated. This is ok and does not violate your architecture. This is what dependency inversion is all about.
Consider configuring "well known urls" at the web infrastructure level (gateway or load balancer for example) so you can have "mycompany.com/user-action-1" in the email and that will translate to the proper endpoint of your web app.

Conventions on having both an API and MVC project in .NET Core solution

I have an ASP.NET Core (.NET Core 2.2) app structured with the following projects:
API: this is meant to represent a WebAPI (with controllers inheriting ControllerBase)
Services: This contains services which the API controllers utilize to access the database, etc
Database: This contains the usual DB repositories, which the services layer utilize to access the database
Now, I want to add a UI that talks to the API (the MVC part pre-.NET-core). How is that accomplished with .NET Core, where MVC and WebAPI are one of the same thing? Should MVC controllers/models/views be part of the API? Should it instead be a new project that listens on a different port? How does authentication fit in for both (e.g. APIs usually have some token-based authentication, UI apps usually have username/password authentication)? Should the WebAPI and MVC portions share the same authentication like ASP.NET Identity? Wouldn't that tightly couple the two if they use the same database?
Is there some kind of Microsoft or community suggested convention/documentation for how to structure such projects?
How is that accomplished with .NET Core, where MVC and WebAPI are one of the same thing?
In dotnet core MVC and WebAPI can be present in the same project. Everything application is like a console application. You can add MVC services to startup class to make it an MVC application.
Should MVC controllers/models/views be part of the API?
Its better to have different controllers for MVC and WebAPI related functions separately while keeping them in the same folder.
Models - They can be reused for both mvc and webapi. Same for view models and DTOs.
Views - Just for MVC, webapi does not require views.
Should it instead be a new project that listens on a different port?
Yes, you can create a different project for webapi and MVC.
How does authentication fit in for both (e.g. APIs usually have some token-based authentication, UI apps usually have username/password authentication)?
If you use token-based authentication then both web API and MVC will be able to use.
Should the WebAPI and MVC portions share the same authentication like ASP.NET Identity? Wouldn't that tightly couple the two if they use the same database?
If you use ASP.Net Identity with identity server then both MVC and webapi will be able to share the same authentication mechanism without tightly coupling.
I think that you are a bit confused about WebAPI compared to MVC.
You can see WebAPI as simple web services answering http request with data (whatever the data is, it could even include javascript or assets).
EDIT:
So sending "UI" informations is definetly a part of your API and Service project.
On API you will need to create dedicated controller(s) to send back your "UI" part(s).
On Service you will need to create dedicated service(s) to fetch the "UI" informations (their is many way to do this, using Ressources, fetching data on Cloud, etc)
EDIT2:
But nothing prevent you from creating an entirely different solution for UI parts. If you chose WebAPI again, you will still need to enforce the previously mentioned API/Service logic. It's up to you to chose whatever you feel confortable with.
The answer to your question is mostly, "it depends on your tastes" but in my opinion...
Unless you are planning on exposing the API to other applications, keep the API controllers in the same application that hosts the MVC controllers (or Razor Page). When I have both MVC controllers and API controllers I put them under separate folders. I think this is OK, because your controllers should be very thin. I generally put all the business logic (including any necessary data access) in services that are built in a separate class library.
You only add an API if you actually need it.
Do you plan to expose anything to another app?
If all you want is a UI which interacts with a database then don't bother, use the services to retrieve the data, called them from the MVC controllers and skip the API part completely.
You don't need an API for such a limited use case. An API introduces a host of other things to consider, like authentication and security.
Don't complicate things when you don't need to.

Implementing field/column level security in a Web API

I have a .NET Web API that allows clients to return details of People and associated data.
There are a number of non-fixed roles in the system (it's multi-tenanted) and each Role has access to particular fields e.g. Admin could see Date of Birth, non-admin can't.
The structure of the application is:
Client Controllers > Business/Service layer > Repositories > Database
Data access is currently being managed through a combination EntityFramework for Add/Update/Delete and Dapper for Queries.
My question is: is there a excepted standard/common of approach of filtering data at field level going to the client, and returning from a client before updating models in the database? Ideally if there was some sample code or application to demonstrate the approach.
My initial thoughts on this are to filter the ViewModels before they get sent to the client and perform checks before updating the EntityFramework models, but this seems disjointed. Also I'm not 100% on the best approach to this either way.
Other possibles I have considered are:
Use a formatter to remove data before being sent to client, and a custom security attribute to filter data before hitting the controller action.
Move away from EntityFramework and implement my own secure Data Access Layer to handle all of this
Implement the security at the database level
A ViewModel per entity per role, although I have discounted this as with non-fixed roles this can blow up quite quickly.
I'm not aware of any frameworks available that offer field-level security but lots of commercial products offer very configurable field-level security e.g. SalesForce, Microsoft CRM, etc.. and essentially I would like to implement something similar but on a smaller scale.

Shared Authentication between Web and class library projects

I have a Solution divided into 3 projects.
Two of them are MVC 5 web apps which use ASP.Net Identity provider.
One is a class library which is referenced by the other projects. All the CRUD actions take place in here.
All the projects point to same DB and operate via EF.
All the business logic happens in the class library but is user agnostic. User validation happens in web apps only. Problems here are user validation code is repeated across all web projects and the class library has no idea of the user invoking an API.
This kind of architecture will bring maintenance nightmares very soon so I would like only the class library to talk to db for business logic or user validation.
Now, since ASP.Net Identity provider doesn't work in class libraries, anybody found a way around it?
I am not sure what "maintenance nightmare" you are referring to by having security in the web application. It is a good thing to decouple your application domain from your security model. Your domain model and business logic may remain the same across certain web applications but the security model may vary. I would not bundle these together. And if it is in your class libraries how will you let the OWIN security framework handle forms authentication for you. Are you going to manage all of this in your class libraries as well.
When you refer to "user validation" I assume you are talking about authorization. If you must perform authorization in your class libraries I would implement a custom ClaimsAuthorizationManager. You would override the CheckAccess method to perform your authorization. The ClaimsAuthorizationManager is configured in your web.config so you could have different ClaimsAuthorizationManager's for different web applications. But the logic in your class libraries would remain the same. Anywhere that you want to authorize the user before performing an action you would insert:
ClaimsPrincipalPermission.CheckAccess("MyResource", "MyAction");
The resource and action passed is used in the custom ClaimsAuthorizationManager you created to know the context in which the authorization is taking place. I talk about this method for decoupling your security model from your application domain in this article. If the authorization fails a SecurityException is thrown. You would let this percolate up to your web application where you handle it appropriately (redirect in a controller or an HTTP unauthorized error for Web APi's). Note that this architecture will work if you use your class libraries in non-web applications as well. I have used this with ASP.NET Identity and it works well.

Where to locate custom membership, roles, profile providers in a 3-tier setup?

I have a 3 tier ASP.NET MVC 3 project that has a data layer, service layer then a presentation layer which calls upon the service layer to get data. I'm actually using the doFactory patterns in action solution.
I want to implement a custom membership, roles, profile provider but I'm not sure exactly where to put it. I was thinking of putting it in the service layer then have the provider call on the DAO objects to get the info.
Any other ideas?
You're thinking pretty well. Though the UI layer interacts with the client and takes their password, your service layer should process attempts the enter system.
Your action methods pass along the information to the service objects responsible for authorization.
Your service layer would have no idea whether it is in a web application or not.
The data layers is just the place where that information is stored, not where it is processed.
You might choose to keep the ID of the user in the UI layer, in session. On login the Service layer would take the username/password/whatever and return a UserID. Or, your action methods could pass in a session key into the service layer each time, to get the User information.
Edit due to comment: I'm doing this in my current project (couple $million scope). I have my security decisions in the action methods. (Though of course the tools for making this simple are objects from the Service Layer.) For example, if the current user doesn't have this role or that role, then redirect them to a rejection page, otherwise, do the thing. MyServiceLayerObject.DoThing() has no security inside it.
It's the simplest way for my app and many others. ("Simplest" means it will will be screwed up the least. When it comes to security, simple is good!) Since the Action method is the gateway to the functionality, having security in the service layer would just cause extra work and actually obscure what security was happening. Now, that's my app, where there is usually one place where each action takes place.
Your app may be different. The more different action methods and (especially) different components are using your Services Layer's functionality, the more you'd want your Service Layer functionality locked down with your authorization scheme. Many people feel that security should always be in the service layer, and that any additional security actions in the UI layer would be bonus redundancy. I don't agree with that.
Here is an existing implementation of Membership Providers in 3 tier world that I found when looking for the same thing...
http://elysianonline.com/programming/wcf-wrapper-for-asp-net-membership/
And here ...
http://elysianonline.com/programming/using-the-wcf-membership-provider/

Categories

Resources