Best Practices in User Privileges/Session Variables in MVC3 - asp.net

Hi Stack Community Members,
I am developing an application under MVC3 where users have department-specific CRUD privileges. In other words, all users can view data for all departments, but only certain users can make changes to the data for any one given department. User-department privilege data is held in a join table in a database.
What I typically do in this kind of situation (in PHP) is to create a Session variable (an array) on login which is populated with the id's of the departments which the user is allowed to edit. When a user then goes to access the editing feature a drop-down list is populated with only these specific departments. I also populate a few other session variables which are used frequently like the user's name and the id of the current time period (business quarter).
Is this type of approach a good way to go in MVC3, or is some alternative approach better? While I figure that I'm going to use Forms Authentication and some specific roles (employee, admin, etc.) these types of roles are just too broad to be able to target department-by-department access, and I'm not sure that MVC3 has an out-of-the-box method which is better than what I'm planning to do.
Your guidance is appreciated!

I'm using Forms Authentication, add specific roles, and combine them if needed. I don't mind being specific for the roles, as they can be combined anyway I want. I can still have broad roles for more general actions.

I store similar data (UserId, DepartmentId, etc) in session since it does not change for the user and it is a small amount of data. It is my opinion that session state would be a good approach for you also.

Related

Oracle APEX User Rights and Previleges

I do not have much experience and I would like to know if there is an easy way to create user rights and privileges, so that each user can access only specific records from the database tables, based on the level he belongs to.
More specifically, suppose we have a group of companies where this group has some companies and these companies have some branches and the branches have some users.
I want the user belonging to the "group of companies" level to have access to and view all the entries in the database related to that group and what is below it (its companies and the branches of these companies).
The user who belongs to the "company" level should have access and see only the files of this company and the branches that this company may have in the database.
The user belonging to the "Branch" level should only be able to access and view this barnch records in the database.
And finally the user belonging to the "End User" level to have access and see only the records created by the user in the database.
Of course level "administrator" will have access to all records in the database.
I thought of creating a user table with a field "User_Level" and in each table to enter USER_ID where based on this I can find the level of a user but how can I restrict access based on the Group of Companies or the Company or the Branch where it belongs?
In APEX you can create authorization schemes to determine what components a user has access to within an application - but that is just a part of the answer to this question. Your question is about filtering the data that is showed to a user based on certain criteria.
There are a couple of possible solutions to this. Since this is a very broad question I'm just going to give you pointers/concepts to start your research. Up to you to determine what solution/combination is most suitable for your implementation.
Concept: Multi-Tenancy
If the data is used by multiple tenants then add a tenant_id to each table that has tenant specific data. In your case a tenant should be a branch. A simple design could be a groups table (to hold branch - companies - company groups), a group_members table (to define relationship between branch - companies - company groups OR between any group and a user) and a users table.
Concept: VPD This is a feature in the oracle database that allows a transparent implementation of security rules. In the application you'll define a simple select like
SELECT * FROM emp
But the VPD implementation will automatically add a where clause to the query to only show the records defined in the VPD policy. This makes developing the application a lot easier since there is less room for errors. Note that this database option could not be included for your licence. There is also something called "Poor Man's VPD" that does not use the VPD option. Google on how to implement this in your apex application.
Just do it all by hand: This is the least preferred option but it can be done. For every component where a select is done, manually add a where clause to restrict the returned rows. However this is very maintenance intensive and there is a ton of room for errors - obiously the data model will still have to support the striping of the data.
This blog post by Jeffrey Kemp might give you some pointers as well: https://jeffkemponoracle.com/2017/11/convert-an-apex-application-to-multi-tenant/ - go through the "further reading" section at the bottom.
you can create a procedure or function and in your app's shared components -> authorization scheme use that such as pl/sql function/procedure returning boolean and return true for the users you want to see the things and false for hiding.
In Apex components, select this authorization scheme like in items, pages etc.

How to manage multiple users with EF in ASP.NET Core

I am designing a database for a language learning center. I have 3 subjects to manage: admin, teacher and student.
Admin can assign the role to the other 2 objects
The teacher has the role of posting instructions on the website
Students can register for the course and pay
Should I create a teacher and a student table in the database? If so - how should I design them? Otherwise how should I manage just one user object?
I designed the AppUser class to inherit the identity user class, the student and teacher classes inherit from the AppUser class, is that a good approach?
A better solution is to create a teacher and a student table in the database. Because their roles are completely different, this can separate their respective businesses completely. Reduce the complexity of design.
Create a login page, you can provide a drop-down list for users to choose their own roles, query the database according to the user's role, and then fill the user and the user's role to identity to achieve authentication.
The question for how to handle this comes down to first separating logic into the "Can do" and "has a" bins.
If your objects have unique relationships, (Lets say Teachers have several Table relations unique to them), then you want to use different tables for them.
If however you can simplify the relations enough that they can be functionally the same (IE both Teachers and Students will have a Classroom relation, which though it means something different for them, can be re-used as the same column for both), then you want to instead handle this difference via Roles.
Roles allow you to apply authorization to various parts of your website.
It might also be best practice to do both of the above.
When handling "multi user type" style interfaces, you typically will need to be careful about selecting how you register users. Do you want to do it via invitation emails/codes? Or perhaps Administrators create the users by hand and there is no form of registration at all?
You can use AspNetRoles table. And bind it to AspNetUsers table. You don't need to create teacher and students table.

Migrate Plone users and groups to relational data

I have a Plone 4 site which contains a lot of users and groups which are stored in the ZODB. Over time, we added some functionality which uses relational data (in a PostgreSQL database); some tables have fields which contain user or group ids.
However, currently the users and groups are defined in ZODB rather than the RDB, so we don't have proper foreign keys here. Thus, the obvious idea is to migrate the user and groups data to the RDB - those who/which are used by the Plone site, at least; I assume emergency users need to be an exception to this (but those are no members of any groups anyway).
Would this be a good thing to do?
Are there reasons to do it only partly, or should I transfer everything including group memberships? (Since memberships are stored as lists of users (and/or groups) with the containing group, I could imagine a reverse table which holds all groups a user is member of, and which is maintained by a trigger function.)
Are there any special tools to use?
Thank you!
imho it's based on what you want to achieve. In Plone you have PAS, so technically it doesn't really matter, where you put users, groups and user group relationships.
You can store users/groups in:
Plone (by default)
SQL - pas.plugins.sqlalchemy
LDAP/AD - Products.PloneLDAP
There are also many other plugins for AUTH, like RPX, Goolge+, etc.
You can enable, disable and modify the behabvior of every plugin thru PAS.
Does it make sense, to NOT use Plone users?
Of course, if you want to share user credentials (Example LDAP), or if you need the user informations in other Apps, etc.
Migration
Should be very simple if the PAS plugins you are using supports "Properties" and "User enumeration".
Get the data from one plugin and put the data into another one with a simple python script. Both supports the same API.
the tool you're looking for is https://pypi.python.org/pypi/pas.plugins.sqlalchemy/0.3
I've used this in a webportal where users are "shared" with a newsletter system.
I've 200 users and any problem.
I think the only "good reason" to store users in an external DB rather in zodb/plone is in a use-case like mine.
Have you ever think about "extend" plone users (ex. https://plone.org/products/collective.examples.userdata)? With plone.api you can easly manipulate users' properties in your code.

ASP.NET Membership - A design for tracking additional information

I'm working on an ASP.NET4.0/C# application for a public site that needs to authenticate only the employees that work at the associated business. The idea is for the site to have a CMS such that employees can go in and make changes to certain content without having to work with any html.
My question relates to the design and use of a ASP.NET membership provider. I'm not trying to make the site work with an existing database, so there's no need to create my own MembershipProvider for that purpose. However, since each user is an employee, I want to track additional information such as name and office number. I can think of two readily apparent ways to accomplish this:
Use the default SqlMembershipProvider class. As a result, I would need to add the appropriate tables to my database and create a separate table for any "additional" information I want to store. This effectively creates a vertical partition on the user table, since I would use the asp.net-assigned userID as the primary key of the employee table as well. To retrieve the "additional" information, I could ask the provider for information about the current user and requery the database in the event I want to know anything else.
Create one table for all employee information (including login and password) and create my own custom MembershipProvider and MembershipUser classes with the functionality I desire.
I've also considered the use of profiles to store such information, however, the site will publicly contain employee listings, and these pages will need to access some of this information. As a result, I should probably cache this data and it seems like using the serialized fields that profiles provide would cause a problem.
Thus, purely in regards to design... would it be best to make a distinction between a user and an employee and use the default SqlMembershipProvider and associated tables, or write my own user tables that store the information I need and my own MembershipProvider for accessing that information?
If I understand your question correctly, you'd like to store additional user info within the ASP.NET Membership. I've created a number of sites using the following setup.
Install the default .NET Membership using the aspnet_regsql.exe tool
Create a UserProfile table with a uniqueidentifier (PK) UserID column that is linked via a foreign key to the aspnet_Users table
To access that information, all you need is the UserId of a particular User, then you can query your custom table for more information.
Microsoft has written an excellent post on how to do this.
Good luck!
M
I am doing something similar, using your option 1. Works great for me.
My business logic has some functions for mutating users. It knows when to touch my users table or the Membership functionality.
Using a custom MembershipProvider for this sort of thing will give you more work than you bargained for.
SQL Table profile provider (http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx ) will help you do just that.
You will get the power of the Profiles and on the same time not worry about caching or serialization since this provider stores the profile information in clear database table without any serialization. You can use them directly in your queries.

Best way to ensure page-level security

I wish to ensure a user has access to an aspx page by 'Zone'. For example, "Financials" is a Security Zone which some users should not have access to.
The result should not involve patterns such as MVP, MVC, MVVM, etc. I'm looking for something that's light and quick to do.
To make things easier I have a base class which each aspx page derives from. What is the easiest/best way to have each page to be checked versus a security zone given the userID?
Thanks.
I've used this, whether it's the best way is seriously questionable. I have a class I derive from Page, called SecurePage. In that I usually have a cross table in a database that lists objects, such as the page, and groups/users that have access to that page. Running a stored procedure using the UserID and the Object name (Page name in this case, but can be a field, or whatever) it returns whether that user or a group that the user belongs in has access. You can check this during the page init, and if it doesn't match up, then response.redirect them or whatever you want to do.
You basically need to create a little ACL implementation. (Access Control List).
Create a acl_roles table, with all your roles (Admin, Accountant, whatever, guest) and stuff. Then link the id of it with your user table, so each user has a role_id.
Then define a acl_resources table, where you add the "zones" in your app and the minimum role they have to be to access it.
Then at the start of each script simply do check if the current user has enough privileges to be in that zone.
There are more details into this, but that is the basic idea.
Yeah, use forms or Windows authentication. You can easily lock down different parts of your site based on the authenticated user's role. Look into using locations.
Why not just use the security features such as forms authentication built into .NET? It's very easy.

Resources