OWIN FLOW (from MVC 5) to Class Library - c#

I've a website with 3 layers.....
MVC 5 (Presentation layer) with custom OWIN to store cookie. It checks with Service layer to validate user and then create a cookie.
Service layer (Class Library): Presentation layer has reference to this layer and any communication with database, needs to go through these.
Data layer (Class Library): Data layer with SQL statements. This layer is responsible for any communication with database. Service layer has reference to this.
All the above mentioned layers reside on same machine but within seperate projects. There is also potential that I've had to move all the layers to its own seperate servers (Presentation, Service, Data).
Now, once the user is authenticated and authorized, I want to basically pass the identity to Service and Data layers as I don't want anyone to call the service and data layers directly. But I don't know how to do it.
Could anyone please show me the light?

Cookie/Token is only usable in browser-based environment (that means it only help to secure your presentation layer.
If you want to secure the Presentation layer (which is class library as you mentioned), quick and dirty way is store a private key inside Web project, and every time you call a service, validate the private key passing in.
Standard way is use StrongNameIdentityPermission to prevent others to reference your DLL. (https://msdn.microsoft.com/en-us/library/system.security.permissions.strongnameidentitypermission.aspx)
Extra note: consider to use obfuscator tool to prevent others to decompile your DLL code.

Related

Moving authentication to service

I'm writing simple CRUD-like MVC app at the moment, trying to learn proper N-tier architecture, and so far i had MVC which gets objects through WCF which call my Data Access layer to get those objects from Database.
However I just realized most likely huge mistake I'm making, I left all generated authentication stuff where it was - in MVC project except ApplicationUser and ApplicationDbContext which i moved to Business layer and Data Access layer accordingly and referenced them which I think defeats purpose of Service. How do I move properly authentication to service in this case? Perhaps there is a sample N-Tier project which has authentication moved to service and all?
So far my references are like this:
MVC client knows about Service(as service reference), Business layer
Service knows about Data Access, Business Layer
Data Access knows about Business layer.
this might help you! this explains asp.net identity with Design Patterns
http://timschreiber.com/2015/01/14/persistence-ignorant-asp-net-identity-with-patterns-part-1/

Replace (Entity Framework Connection) to (WebServices) on Services Project

We have the following structure on our project in order to get data.
Acces to Database Using Entity Framework
ProjectName.DAL
Services that call Entity Framework.(UoW)
ProjectName.Service
Our Actions inside Controllers call Services and return data needed.
ProjectName.Web
The Question:
Our services take info directly with Entity Framework, What are the advantages and disadvantages about creating WebServices in order to replace the connection with EF? "In that case only WebServices will have access to Entity Framework,"
ProjectName.DAL
ProjectName.WebServices
ProjectName.Service
ProjectName.Web
The main advantage is that you would have a more decoupled design.
By exposing your DAL through web services you "disconnect" it from your frontend. For example, a mobile app, a web app and a WPF desktop app could all access your DAL through the same web services. So you can reuse your DAL accross different apps which can save you a lot of development time. Have a look at ServiceStack and advantages of its web services.
Disadvantages? Having to do some additional development work and testing. If your app is a simple and will not be used in different environments it may be overkill to use web services.
Disadvantages:
Web services tend to consume more resources from your server than just a plain CLR (aka dll) layer in your project.
whatever web service you plan to use (legacy web services, service stack, wcf, Web API, etc) you'll find that all of them have to use a process to serialize the data and it could be the case that you'll need to do the inverse process in your front end application.
you have to design your ws very carefully because you have to think how you're going to expose those services and the level of encapsulation/abstraction you will have to put in place, a bad design in a web service layer definetely will be a headache for you during development and production.
Security: In most cases you will have to validate every input in those web services as well
Advantages
well that's very relative to call an advantage, it depends more on what are your app requirements, some questions you need to answer are like the following:
Do I need to share data with other apps (mobile, desktop, other web
apps)?
Do I need to expose some functionalities to other business (third
parties)?
Recomendation
If you plan to do a CRUD application I'll recomend to go with REST definetely is the best option due to it's architecture (POST,DELETE,GET,ETC).
if you don't need you a web service right now, you can try to develop your service layer kind of like a service implementation in service stack but try to remain as POCO as possible and if for some reason you'll need a web service you can try to refector the service layer intead to have another level of indirection in the middle.
just my two cents...

Where should these classes/methods go?

I have a structure like this
WebUI project - controllers, views
Framework project- repositories,service layer and domain
So now I have 3 methods/classes
Open Id/Open auth
At first I thought I would put all my logic in a service layer in my framework project(preparing the request, checking the response and etc would be in this layer).
So now I am using the dotnetopenauth library and because I need to use the AsActionResult method in my controller(I return "OutgoingWebResponse" from my service layer as I don't want anything MVC in my service layers)
It got me to thinking when I decided not to have anything MVC in my service layer. As what I read is that your service layer that contains your business logic should not have any dependencies like MVC references because if you go to a windows phone application you should not be using MVC stuff.
Your business layer should be sort of plug and play into any application.
So now I am not sure if I should move what I wrote for openId into my models folder in my mvc projectjust for the reasons above. Since if I do go to a windows phone application or forms application I won't be using dotnetopenauth since I don't think it's supported in these types of applications.
My second one is with forms authentication. Again pretty much same reasons as above. Should this go as well in my models folder as a local service/repo layer(ie in the same project file).
I am using nhibernate, fluent nhiberate and ninject. My repos are all in my framework project. So I have of course all the references in there. But since I am using ninject for ioc I have all the references in my webui project as well.
I have no clue if this one could be changed to get rid of these references from my webui. I am thinking no because they I can't have my ioc in my webui where I think it should go.
As a general rule of thumb you shouldn't write code against requirements that don't exist ( porting the app to a windows phone ) .
Normally you'd abstract this out in your service layer however OAuth or Facebook integration poses a problem because of its reliance on http and being able to visit the authenticating site.
The problem you'll run into because "all abstractions are leaky" is that your service layer will be corrupted somehow by the openauth registration process regardless of where you place it. Details about user registration and login such as what their openid url is will end up in your database. You're service/repo/db/model/mvc/viewmodel/controllers classes are all going to know what openauth is because of its nature.
The good thing is these browser based authentication strategies can live in a Windows Form, WPF or Silverlight application. You simply open a browser inside the application instead of redirecting natively with MVC.
So what I'd recommend is placing your dotnetopen auth registration code inside of your service layer and actually abstracting out how the redirection and callback process happens.
Something like:
public interface IOpenAuthRedirect
{
public void Redirect( url )
public void ParseCallback( url )
}
public class MVCOpenAuthRedirect
{
public void Redirect(url)
{
HttpContext.Current.Response.Redirect(url);
}
}
public class SilverlightOpenAuthRedirect
{
public void RedirectUrl( url )
{
SomeBrowserControl.IForgetTheCallToRedirect( url );
}
}
Now the different implementation details are flexible and you can easily transition to another platform besides MVC.

Authentication and authorisation in an n-tiered architecture

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()

WCF Data Service - Proxy mid-tier service

The project we are working on is a classic 3 tiered architecture. tier 1 being the database server, tier 2 the application services and tier 3 the presentation tier (a web site).
In the application services tier I have a project that includes an entity framework model and a WCF data services based service that exposes the entities within the model e.g.:
public class DataService : DataService< PortalEntities >
This is a fully fledged OData service that can be queried through the URI e.g.: /dataservice.svc/mytable?$filter=contains(fieldname,’string’). This is great for the guys developing anything using jQuery as all they have to do is define the query. The problem is that this service is a mid-tier so it cannot be seen by the outside world.
The solution that I am trying is to expose another WCF data service on the web site that exposes the entities created by the service reference. If I add a service reference to the mid-tier service it gives me a data context that data context is being used in the new WCF Data service:
public class DataService : DataService< PortalEntities >
I do have to overwrite the CreateDataSource:
protected override PortalEntities CreateDataSource()
{
return new PortalEntities(GetMianModelServiceUri());
}
The new service does act like a proxy and does return the entities exposed (the query .../Services/OData/DataService.svc/tbl_Country works fine).
But when a query is passed to the service e.g.: .../OData/DataService.svc/tbl_Country?$select=Name it throws a not implemented exception.
Any ideas on how to extend the web site service so that it supports the same queries as the mid-tier service?
If you don't need to change the shape or functionality of the data server, you should be able to simply forward the requests and responses, just like a transparent HTTP proxy. The only difference you might need to do is to tweak the service URL. Since the proxy service will have a different base URI than the real service, the payload would contain the real service URIs (in the links and such), which would not work. You can workaround this by using a custom host for your real service and lie to it about its URI. This is done through IDataServiceHost2 interface, you return the "new" URI from the AbsoluteRquestUri and AbsoluteServiceUri properties. Nice sample of an implementation of the interface (although for a different purpose) is here: Link.
If you need to change the shape or functionality, then you really need a true layering.
Layering one WCF Data Service over another is currently rather hard. The LINQ expression trees generated by the "Server" are not always understood by the "Client" LINQ provider. That's what you're running into.
There's a prototype (more like an experiment) of making this work to some extent by rewriting the expression trees. It's part of the OData Provider Toolkit which you can download here http://www.odata.org/developers/odata-sdk#/media/7579/odataprovidertoolkit.zip. (It's in the Experimental folder, AstoriaOverAstoria project).
But please be aware that this is really just an experiment to show what kind of issues are there to be solved and so on. I definitely recommend to NOT use it in any kind of production environment.
I have found it possible to expose a service on the Web Tier that references a service (not data directly) on the App Tier. This only works for queries at the moment. I am not sure what is needed to get it working for updates, deletes etc. Any Ideas anyone? Anyway, here are some instructions and code snippets:
First you create a WCF Data Service on the App Tier bound to your edmx model.
Then create WCF Data Service on the Web Tier not bound to an edmx model (custom).
Create a Service Reference in the Web Tier Service to the App tier service.
Pass the Entities type to the DataService generic declaration (should be angle brackets for VB but I couldn't get them to show:
Public MyWebTierService
Inherits DataService[MyServiceReference.MyAppTierEntities]
Add an override for CreateDataSource() that creates your reference to the App Tier:
Protected Overrides Function CreateDataSource() As MyServiceReference.MyAppTierEntities
Dim ctx = New MyServiceReference.MyAppTierEntities(New Uri("http://yourappservicelocation/AppService.svc/"))
Return ctx
End Function
All you do now is create a reference to the service or bind it to your client app that
supports OData. JSONP support can be added if required.
So, this works fine for Queries but not for updates, probably because the Types are not the same (they may look the same, but are in difference assemblies after all). So, tracking is lost between the Web and App Tiers.
It may be that we have to implement IUpdatable on the Web Tier to solve this. Not sure yet so any input would be useful.
Hope this helps

Categories