ASP.NET Membership - Logged into two places at once - asp.net

We have got two distinct lists of users that we need to power logged in access to sections of our site.
These lists can't be combined, as one is synced daily to an externally hosted data source, and both tables have to be 100% the same.
We have set up two Membership providers onto the site, but my question is, is it possible to allow both to be logged in at the same time?
The issue I find is that HttpContext.Current.User.identity.name contains the username of the last successful logon.

Use some sort of delimiter and put both users into the the login Identity. e.g. mp3duck/employee1
When you login in via membership provider 1, you would do something like
// extract the existing prov2ID so you can keep it. GetID() would be a string split function
string prov2ID = GetID(User.Identity.Name, 2);
FormsAuthentication.SetAuthCookie(prov1ID + "/" + prov2ID, false);
And visa versa for a login via membership provider 2.
If you are using the <asp:login> control, you would modify the UserName propery instead of calling SetAuthCookie() since the login control calls SetAuthCookie() itself.
You can put any sort of stuff into the Identity name. I often use it to store both a number int ID for the user primary key, and their username. The only downside is you have to clean it up when displaying it in the html. e.g. Hello <% User.Identity.Name %> would display a lot more than you wanted.

would the suggestion outlined here be of any help?
Can SiteB Restrict Access Only to Users Authenticated on Site A? How?

Related

Ensuring user is updating its own record

I'm building a simple web form which allows user to edit there data like email, emergency contact etc.
The edit form is rendered using Asp.NET MVC 5. Proper html fields are rendered for Id, email, emergency contact etc.
Lets say the request to save the data is received by the following controller method.
SaveData(recordId, email, emergencyContact)
{
;
}
Question: How do I make sure that recordId was indeed the id that was rendered as part of the edit form? We don't want this user to update another user's record.
I have the following options in mind
1. Create a hash of the record id and send the hash as well.
2. Ensure user is authorized to modify the record indicated in given record id.
Is there any other way? Does MVC 5 provide any features so that I don't have to put this sort of logic in my application logic?
Typical approaches are:
Store the ID of the record as a hidden field. If you are concerned with hijacking, encrypt the value and decrypt on the server.
Store the ID of the record in session; this way, you always pull back the record and keep the value on the server. But when session dies, so does the link to the record.
Yes I'd highly recommend check permissions to the record if you store the ID in the URL.

ASP.NET How to Apply Roles & Members Read/Write Securtiy to Pages, Sections, Fields, & Records

I've built a number sites using classic ASP type security and have continued using the same methods in ASP.NET. However, I now am looking for recommendations for a better or best practice way of doing it. I've read a few resource online but have not seen anything comprehensive enough that's applicable to what I'm trying to do. What I'm trying to do is apply user specific security that determines that user's access to specific pages, sections on that page, and fields in each section. It also needs to restrict access to various records as well and determine whether it's read or write privileges.
For those interested, here's how I've done it so far:
Because I lacked the know-how, here's how I did it using the old ASP classic way...
First, on the database side I have 4 relevant tables: tblUsers, tblRoles, tblPages, tblRecords (haven't gotten to sections and fields yet). Each user can belong to a "role" and the role then determines what pages they can access as well as what records they can access in various tables (there are a number of other tables in the db as well e.g. tblCustomers, tblSales, etc...). Each table includes these fields:
tblUsers: UserID, UserName, UserPwd
tblRoles: RoleID, RoleName, UserID
tblPages: PageID, PageName, RoleID
tblRecords: RecordID, RecordTable, RoleID
Now on the application side here's what I've done:
First, my login page is based on 1) looking up the user name and password in the tblUsers table and 2) if found, setting a session variable named "UserLoggedIn" = true. Then on every page load event I check if the UserLoggedIn session is set to true, if so, continue... if not clear all session variables (log out) and send the user back to the login page. The old classic ASP way of doing it.
Second, with the login set up, to control page access, when the user is logged in I created another session variable that holds a pipe delimited string of all the pages that user can access (e.g. Session("PageAccess") = "{1|3|10|8}"). Then in each page's load event I've explicitly added a variable/constant that uniquely identifies that page (e.g. pageone.aspx has Dim PageID As String = 1). Then I check to see if the PageID matches an ID stored in the PageAccess session. If it does, continue... If it doesn't I send them to the home page.
Third/Last, for the records access, I did the same thing. When the user is logged in I created a session variable that hold a pipe delimited string of all the records the user could access along with the table it's related to (e.g. Session("RecordAccess") = "{tblCustomrs||1|5|7}" and checked it and applied it basically the same way as the page session variable.
My Solution is :(it worked for my projects)
tables : tblUser , tblRole ,
tblUserInRole : userid,roleid,username,password (this design help you can assign more than one role to a user)
tblrole, tbrules(your Access Controls for example pages)
tblRulesInRole : roleid , ruleid,Editable,Viewable,printable,Deletable
For Implement Access Control in every request and response ,you should Create HttpModule......

Allow asp.net sqlmembership users to create "subusers"

I've tried searching this for days and can't seem to find an adequate answer so I'll ask here.
I'm building an asp.net Membership website.
What I want to do is:
Allow a user to create an account - say UserA
I then want to allow UserA to create "sub accounts" tied into his account, but with different roles as well as different login names (I'll be using email address as the login name)
UserA would be the account admin of sorts.
UserA's sub accounts would be less "adminish" than UserA, but any data that they write to my DB (Entity Framework) would still be tied to the main UserA account which will be referenced to my tables via Membership.GetUser() API calls.
So 2 questions:
1) How would I reference the Membership tables in my EntityDataModel using DB First (I already ran the aspnet_regsql.exe)
2) How would I need to go about allowing UserA to create his own sub users?
Here's an image of my custom tables:
[MasterAccountUser]
MasterAccountId = aspnet_Membership.UserId
AccountNumber = autoincrement number
[UserAccount] - subaccount of [MasterUserAccount]
AccountId = aspnet_Membership.UserId (if I have to have each user create their own)
MasterAccountId = aspnet_Membership.UserId (but the same one as the [MasterAccountUser]
If this is too vague, let me know and I can expand.
I was able to get this to work.
Basically, you just do the standard aspnetdb.mdf with all the in-place security features.
Then you simply add a table with the same fields, and then you reference the
MembershipUser.GetUser(Page.User.Identity.Name);
So you own table will have a "masteruser" with this User.ProviderKey. Every "sub-user" then has the SAME masteruser guid on their record so that they all fall under the same account.
If anyone want more details on how i got this to work, i can happily provide them.

Adding an integer ID to ASP.NET Forms Authentication

In the standard forms authentication, users are identified by a Guid. I want to give my users an UserId of type int (doesn't have to be the primary key, just something to do lookup's on).
Is it safe to add an additional column to the aspnet_users table, or should I create a new table which FKs to the UserId column and has a Unique column which generates the integer ID?
The later sounds like a bad performance hit to take just for the sake of an int!
EDIT
I want to create URLs like those on stackoverflow. eg. https://stackoverflow.com/users/23590/greg-b where the User ID is an int. For that reason I don't want to use Guids.
I'd create profiles and store the associated urlID there. Web Forms don't have Profiles available out of the box, but you can see a workaround here:
http://www.codersbarn.com/post/2008/06/01/ASPNET-Web-Site-versus-Web-Application-Project.aspx
The advantage of using Profiles is that you can tap into all the existing logic and won't have to write as much custom code yourself, aside from constructing the URL.
You could combine this with Routing for friendly URLs, if you're using ASP.NET 3.5 or up.
UPDATE: kinda similar question:
Shorter GUID using CRC

Membership switch from ID to email

Currently I have a site (asp.net 3.5) that uses a unique ID for the login. I am going to need to switch it to use emails if possible. I am going to be creating all new accounts so I can wipe the membership table clean and import all the user info.
We are switching from generic logins for departments to individual accounts.
Any links or pointers in the right direction would be greatly appreciated.
So here is what you should do.
If you are creating a entire user base just wipe of the current ones and tell users to create the new user with a email, as long as you validate that on the entry form you are going to be good.
Now if you already have a user base, then is a little more complicated.
First verify that every current user has a valid distinct email, then you have to change 2 columns on the aspnet_Users table, the columns are UserName, and LoweredUserName.
That should be simple if the first step is true, just do a loop for every aspnetMembership row, get the column Email and set as UserName, then get the column LoweredEmail a set as LoweredUserName.
Ta daaaaaa!
Now you have it all migrated to the new model, for new entries, make sure that the entry form validates the UserName to be an email, for that you can use RegEx.

Resources