I am working on a railway web application and I have following layers:
ASP.NET MVC 2 (Presentation Layer)
Services Layer
Repository Layer
Database & External Web Services as data sources (Using Entity Framework for Database)
I pass Domain Entity Objects from Repository to Service layer and thinking of passing View Models from Service to Presentation layer.
Website would require a login and after successful login I have to present a search screen with basic search (as default option) and option for advance search. Once user fills the search criteria I have to gather data from DB & Web Services and present the results to user. User would select a particular Rail option and would move on to other additional options page BUT they should be allowed to change their previously selected Rail option by going back to Rail search results. I have to always hold and present user’s initial search criteria (basic and advance search options selected by user on the search wizard) on every screen and need these criteria in Service and Repository layers.
What is the best way to hold these search criteria and pass them from page to page within presentation layer and across layers? Should I create a View Model class for Search Options? Or a Domain Entity Object (I don’t think so)? Or a DTO? and best way to pass it across layers and from page to page with in presentation layer.
Related
I need some advice on how best to implement a security mechanism in a ASP.net core application. The application users are authenticated using AD authentication. Is there a best practice for this type of implementation?
I have a list of project records. Users should only be able to retrieve a list of projects that they have permission to access. I have three user types that have different levels of access as detailed below.
Approvers – assigned to individual projects.
State approvers – Can view state-wide projects.
Global approvers – Can access all projects.
Does anyone have any suggestions on what model and logic to implement to achieve what is required?
Well, I secure pages with information "limited" to logged on users. So if they have membership in a particale role, then only those users can jump/see such pages.
However, in your case, and often?
Well, it not so much the web page the user can use, or be restricted from.
However, when a web page can be restriced based on IIS security and not your code, then that option should be used.
However, often in code, for example, we have indivdul users from a given company, and ONLY some can and are allowed to see all projects. (so some only can see their own projects, but from that company, some have rights to see + use all projects.
So, we often have code say like this:
Dim cmdSQL As New SqlCommand("dbo.GetProjects", GetCon)
cmdSQL.CommandType = CommandType.StoredProcedure
cmdSQL.Parameters.Add("#LogonID", SqlDbType.Int).Value = Membership.GetUser.ProviderUserKey
cmdSQL.Parameters.Add("Email", SqlDbType.NVarChar).Value = Membership.GetUser.Email
cmdSQL.Parameters.Add("#PortalMaster", SqlDbType.Bit).Value = IIf(Roles.IsUserInRole("PortalMaster"), 1, 0)
so, if the user is a PortalMaster, then they can get and see all projects belonging to that company. (each company that logs into teh site can have 1 or 20 employees that belong to the given company).
So, in above, the query going to pull projects by EmployeeID (their logon), and thus they can only ever see their own projects.
If you are a member of the PortalMaster group, then we pull projects based on ComapnyID.
So, while you might not be using the older secuirty provider like above? Your queries that pull projects simple have to restrict rows returned based on above.
Once those projects are returned (in a nice grid - searching options included), then they can select (click on) a project. that next page does not really care anymore, since you can't get to the project details page until you selected a project.
So, obvious you must have for a given Project who created it. And thus your ability to display their current projects will be restriced based on their logon ID or whtever you using now.
But, for state level users? Then your critera is by their logon id and their state they belong to based on that logon.
And then there is the "admin" role or group - they can search and pull on all projects.
So, while we do restrict web pages by "role" security (based on IIS), that just means that all users can, or cannot hit some web pages based on their role memember ship (and such security does not require code on my part - the IIS secuirty assinged to those web pages can do all that dirty work for you.
However, if you are a legal logon, then you can only ever work on projects that belong to your company. But then it is a question if that user also has the role of "PortalMaster", and if they do, then we pull all projects for display to select from for that given user.
And of course we never use say URL "query parameters", and such internal database company ID, or ContactID (user id) are never exposed, nor possible allow display of information or data that don't belong to the given user.
So, you need to build some sql or some store procedures, and having a few "parameters" for those stored procedures that returns rows of data based on their role membership is quite much how you would approach this. So in above, if the user is a portal master, then the stored procedure simple queries the data based on company they belong to as opposed to their contact id.
Now, this of course asseumes the database schema is setup, and for example, we hvae a company table, a employee table (that has their logon information), and then of course each project created has both a created by, and the company the project belongs to. So, that simple information is enough to provide the 2 levels of security.
We actually don't have a "super user" that can look at and see all projects in the system, but it actually not all that bad of a idea, since for testing, or checking a project that has some problem is a "pain" right now, since we in theory have to create a logon for that company, or get a password.
So, all logons we create belong to a given company. And thus when a user creates a new project, it can only be created under that one company, and of course a project also requires the user that created the project.
So, you simple have to restrict records returned in the page in which they can select a project to work on. IIS security, or in fact SQL server security as a general rule can't do this type of security for you - you the developer have to.
I am using web api in my project to expose data which in turn is intended to be used by a mobile application and a web application.
I want to know what is the best practice to expose data.
For instance, I have a customer registration form in which I am capturing Customer details including city and country.
One way to expose the data is to have separate Controllers for cities and countries and make separate calls to both on the customer registration form in order to load the data for cities and countries.
The issue with this approach would be that if I have to load hundred fields, I will have to make hundred different call to the api to load the data and hence the application will be slow.
Second approach would be design the api layer in such a way that one controller expose all the lookup data (cities, countries) required for a form/screen (customer registration). In this case I will have to make a single call to the api to get all the required data.
It feels like, using the second approach I am violating separation of concern.
Which way to go?
Can't you just split UI and API layers?
I do not think you should create API to fetch countries or whatever else side-references if they are not core parts of your domain.
I guess you should just expose api/v1/users resource endpoint for user registration, which expects a valid user data for registration.
Plus you should expose /users UI, which will generate full UI, including all the lists you need and present it to the user. This UI controller will call your domain model internally, not via API to get all the details, needed to generate UI. And then UI on the client side will call your API controller with user selected data to register user.
Will that suite your development model?
The ability to add, update, and delete various entities in my application is often determined by the relationships defined between the various users involved. Here is an example:
A basic user or his supervisor can create tasks associated to the user, but only his supervisor can lock down the task so that the basic user will not longer be able to add/update/delete it. Until locked down, both individuals will be able to update the task.
What is the best approach to implement these kind of complex and advanced rules that deal with the relationship of users and the state of the entities (new, existing), as well as other things like maybe a user-defined status associated to the entity?
Thanks
What is the best approach to implement these kind of complex and advanced rules that deal with the relationship of users and the state of the entities (new, existing), as well as other things like maybe a user-defined status associated to the entity?
You want to use an authorization standard, namely XACML, the eXtensible Access Control Markup Language. XACML is:
a standard developed by OASIS, just like SAML is
a standard that focuses on fine-grained access control: access control that takes into account user information, resource information, state, and contextual information
a standard that implements the attribute-based access control (ABAC) model: the user information, resource data, and state can all be seen as attributes
a standard that uses policies and rules to structure the attributes and grant / deny access: XACML is policy-based
a standard that can be applied across multiple layers e.g. across the presntation tier, the data tier, the business tier of an MVC application
a standard that can be applied to multiple technologies and languages e.g. C# (MVC4 and more), Java, Python...
With XACML, you can easily implement relationships e.g.: an employee can approve a transaction if and only if the transaction amount < employee approval limit AND the transaction is not locked.
Where to go from here?
Check out NIST's page on ABAC.
Check out OASIS XACML's page and spec
Check out existing implementations (open-source and vendor such as the one I work for, Axiomatics.)
At a bank I worked for, we had a loan management system that allowed the entire bank hierarchy to see loans in their reporting structure. For instance, a Market exec could see the loan portfolio of all of his/her reports at once. Additionally, s/he had the ability to select from a list of all reports' (direct or indirect) names to view the portfolio of that employee.
It was complex, but we had to maintain an HR database of the reporting structure. Once we had that, we built user functions (could be done as stored procs, too, but user functions worked well in our LINQ to SQL backend) that allowed us to check whether user x supervises user y.
So, in your example, as long as you know who owns the task, and have access to a method that can be used to determine if the task owner reports to the currently-logged-in user, you should be able to easily enable/disable the "lock" button on the page.
The legwork lies in creating that reporting structure DB, and keeping it up to date!
My company has a 3rd party web service we are designing a front end for. The "objects" used by this web service are very large (and variable depending on the number of sub-entities created). The web service does not expose methods to commit/load sub-entities, only the full object hierarchy.
The UI itself is split into many sub screens, and master/detail views to be able to efficiently/easily edit the large amount of data.
The issue is where to store all the data you aren't currently looking at.
Doing the web service commit takes up to 30 seconds for large records, so it is not feasible to use the web service for the intermittent data storage.
You can consider using .Net's SessionState out of the box, with the SQL persistence mode to cache the web service data, although you do need to ensure that you have a strategy to clear out expired data from the database. All objects stored in SessionState will need to be Serializable.
Also, instead of using the external web service's entity structure (e.g. the serializable proxy entities generated by a .Net added Service Reference), you should also
consider building your own customized class hierarchy for your screens (i.e. custom view models), and then build the bridging to map / project the web service graph to your viewmodel after the initial fetch from the web service, and then back again to the web service entities after the user has finished updating the graph. LINQ is great for this purpose, or possibly AutoMapper, if you haven't deviated from the web service class and property naming standards.
I am in the process of developing a web based solution do replace an application we provide. The web application is a record storing application and each client would have different forms they would input data into and store. My question is: Is it possible to create a backbone Web Project, which would have minimal updates this would be like a container and be the same for all of our clients, and have the document forms which would be different among clients and need to be updated more often.
Any constructive comments for or against this with reason why would also be appreciated.
It sounds like what you’re describing is a multi-tenant system if you'd like to do some research on that term. Your web interface remains the same for all, but the records/documents are different for each client. It sounds like you might need login/access functionality that ties the records to a client ID (possibly stored in a database). According to how you intend to store the records (file system vs. database), you can control access either based on the client ID (foreign key to the doc tables) or you might want to create roles. This is a very high overview for what can become complex according to the specs.