I am using the ASP.NET inbuilt login and role management solution (creates table like aspnet_Users etc. and gives access to MembershipUser and the such).
However, at this stage I am a bit stuck with the following:
1) I need to be able to Suspend, Unsuspend and Delete (not necessary remove from table, just disable) users from my app. Is this feature inbuilt?
2) I need to have three different user roles, where one of the roles is always assigned by default. Currently I have built an app with no roles. Is ASP.NET capable of doing this?
ASP.NET Membership has concepts for "Approved" and "Locked out" (after X number of failed log in attempts) for users, you can probably use those features for suspending users. 4guysfromrolla.com had a great article series on Examining ASP.NET's Membership, Roles, and Profile , it's worth a look.
I don't think that's available by default, but should be fairly easy to add in.
Roles are supported in the default implementation. However, you'll have to define and assign the roles yourself.
There is a built-in DeleteUser
method. It calls a stored procedure
named dbo.aspnet_Users_DeleteUser.
You can change that stored procedure
to suspend a user instead of
deleting them.
Similarly, there is a built-in CreateUser method which calls a stored procedure named dbo.aspnet_Membership_CreateUser which you could modify. Or, you could use the Roles.AddUserToRole method to set the default role when the user is created, calling it in your CreateUser method (which would first Membership.CreateUser)
Related
I have three levels of users in my website, Managers,employees and normal users. Each of them in different table in my database.
I created a log in form using login tool. Then I created connection and sessions.They work fine.
now my question is what is the best way to check the session in all pages (if it is manger, employee or user). it would be more useful if there is example :)
Thank you for your time.
Pretty traditional and simple, you could use this tried and true method.
Essentially you would use the UserData property of the authentication ticket to store the current users' roles. You can then obtain the data at any time from the current thread's principal.
I have a project that is not released yet I will not be soon but I moved it from mvc3 to mvc4 a few days ago and while reading I saw this new security provider SimpleMembership.
The way I implement security now is by using MembershipProvider and FormsAuthentication:
I have implemented ICustomPrincipal
I have implemented CustomPrincipalSerializeModel
I have implemented IPrincipal
To register user I use:
MembershipCreateStatus status;
Guid g = Guid.NewGuid();
Membership.CreateUser(model.User.Email.Trim(), model.Password.Trim(), model.User.Email.Trim(), null, null, true, g, out status);
if (status == MembershipCreateStatus.Success)
...
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
tUser.Email,
DateTime.Now,
DateTime.Now.AddDays(60),
true,
userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
...
But as I saw SimpleMembership looks much cleaner and I want to move project to it
but I have some questions about it:
1) I use stored procedures for all database actions I don't use EF at all. If I use SimpleMembership is it possible to use it without EF?
2) Do I need to build custom SimpleMembership for real world application?
3) I saw that it seeds database Create tables. I have my tables Users, Profiles, Roles and UsersInRoles can I apply it to my custom schema?
4) If I want to call WebSecurity.CreateAccount(...) and I want to call some my custom method from domain project that is responsible to call stored procedure that create user do I have to make it custom and if I have to do that is there some resource that explain how to make it custom for users and roles?
To understand SimpleMembership and how it has evolved from, and depends on, the previous Membership implementation, I recommmend reading the original reference "Using SimpleMembership With ASP.NET WebPages (Matthew Osborn)", and my more detailed answer to "What is MVC4 security all about?" to understand it better. To summarise those references:
SimpleMembership
is a term that covers both the SimpleMembershipProvider and the SimpleRoleProvider
is a storage and functionality provider that is used with Forms Authentication
works within ASP.NET Forms and ASP.NET MVC websites, and can also be used within ASP.NET Web API and SignalR, to provide a unified authentication and authorisation model
SimpleMembershipProvider
adds new features to the original MembershipProvider through the ExtendedMembershipProvider abstract base class, such as integration with OAuth providers out of the box
creates 4 default tables which you don't/shouldn't interact with (webpages_Membership, webpages_OAuthMembership, webpages_Roles, webpages_UsersInRoles) and one (UserProfile) which is yours to structure as you wish
works with the WebSecurity helper class to add new functionality
Moves from the "user profile" stored in a single xml field in the original Membership, to a more manageable property-per-column in the new UserProfile table (which is fully customisable using EF)
To answer your specific questions:
1) I use stored procedures for all database actions I don't use EF at all. If I use SimpleMembership is it possible to use it without EF?
You would not generally interact directly with the tables prefixed with webpages_ as there are API level functions in Membership, WebSecurity etc. to do all the business functions you require. However there is nothing to stop you interacting with UserProfile through stored procedures, and if you didn't want to take advantage of the APIs, you could even interact with the webpages_ tables through sprocs as well (but you would just be duplicating all the benefits of SimpleMembership if you did).
2) Do I need to build custom SimpleMembership for real world application?
That very much depends on what you want to do, but as yet I have not had to do this for any real world applications. I have built on and added to the existing APIs, but not replaced them.
3) I saw that it seeds database Create tables. I have my tables Users, Profiles, Roles and UsersInRoles can I apply it to my custom schema?
If you were migrating to SimpleMembership you would have to port the data in these to the tables webpages_Membership, webpages_OAuthMembership, webpages_Roles, webpages_UsersInRoles and UserProfile. However, note that UserProfile can be called anything you want, you don't have to call it UserProfile.
4) If I want to call WebSecurity.CreateAccount(...) and I want to call some my custom method from domain project that is responsible to call stored procedure that create user do I have to make it custom and if I have to do that is there some resource that explain how to make it custom for users and roles?
Its a little hard to understand your requirement, however WebSecurity.CreateAccount does the following:
Creates a record in webpages_Membership and
optionally adds properties to UserProfile if you use WebSecurity.CreateUserAndAccount
If you wanted to do other actions across your database you would then need to call that after your call to WebSecurity.CreateAccount. You can make this transactional by using TransactionScope
If however you wanted to wrap this all in a single call to WebSecurity.CreateAccount and make it call your own domain methods and stored procedures you will have to create your own provider by inheriting from SimpleMembershipProvider (or from ExtendedMembershipProvider). When WebSecurity.CreateAccount then calls ExtendedMembershipProvider.CreateAccount it will defer to your custom logic
Summary
So would I migrate? The benefits of SimpleMembership are meant to be:
UserProfile: property-per-column storage of user data that plays well with EF or any other db development method
Integration with OAuth, allowing you to use Google, Facebook etc. authentication with very little effort
High level business function APIs in the form of WebSecurity, and continued support of existing features with Membership
Continued support for Roles that works with the Authorize attribute
Integration with EF so that you can use UserProfile along with your own tables
Integration with standard Forms Authentication for ASP.NET Forms and MVC, and also with SignalR and Web API.
If those help you out, then migrate, otherwise spend your dev time on new features for your application.
If you do decide to migrate, then "Migrating Legacy Apps to the New SimpleMembership Provider (Paul Brown)" is useful, which is summarised as:
Modify UserProfile to have a field per property for your old user profile properties that were stored in xml
Migrate your data from the aspnet_ tables to the webpages_ tables
The first time each user logs in again, update their stored password to use the new hash model instead of the old Membership one (see the footnote to my answer here for how to do this)
#Andy Brown makes a lot of good points. I would note to anyone who lands on this that Simplemembership is basically dead and was short lived with ASP.Net Identity coming out shortly after it and is what is used in all new projects. Such a short lived membership product.
I'm building an web application that I want users to have specific permissions to perform a specific action. I don't want to use the default permission and role providers in ASP.NET.
I was thinking of having each User associated with a Role. Each Role is mapped to a set of Permissions (CreatePost, ReadPost, UpdatePost, DeletePost and so on).
I have a couple of questions regarding this. Would it be best to have a boolean property for each Permission on the role or some sort of bitfield? I like the idea of having methods for this but properly need to map these to the permissions stored for the role in the database.
Also, how would I implement this for each action/request? I'm thinking something along the lines of what was posted here but I'm not really sure.
Thanks!
Make your own role provider and register it in the web.config. Look at the MSDN for a sample. Once it is registered it will associate the roles you provide with the principal.
I've just done that for one of my project and it works fine.
To check whether the user has permission to execute a task you'll have to see whether the user is in the required role. In "normal" ASP.NET you will have to do this in code. In MVC you can do that with attributes on each class/method in the controller.
I am using .NET 3.5.
Also, Forms Authentication is used.
Is there any way to get the list of ALL logged-in users or a count in ASP.NET?
Note: I am not using Memberships and Roles
No there isn't unless
You have defined one in your own code
You are using the default ASPNET Membership Provider which has a GetNumberOfUsersOnline() method defined.
You are using a custom Membership Provider and have provided an implementation for the GetNumberOfUsersOnline() method yourself
The default ASPNET Membership provider calculates number of users online by querying the SQL Server database and checking the LastActivityDate stored against each user against the defined UserIsOnlineTimeWindow property that you can set in web.config. If the LastActivityDate is greater than the current time minus the UserIsOnlineTimeWindow value (which represents minutes), then a user is considered to be online.
If you wanted to do something similar then you might consider implementing a similar method. you can see the code for the default providers by downloading the source code. To complete your picture, you might also want to run aspnet_regsql.exe so that you can see the stored procedures that the default providers use.
Membership provider do have its benefits but just to track the users online you can also:
Add a column LastActivityDate to your user table and update it from your code during login and on all page loads for that user.
And to get the usersonline for the past X minutes just use the following sql
Select * from Users where LastActivityDate >
DATEADD(minute, -(X), GETDATE())
Forms Authentication stored all it’s
state in a cookie that is passed to
the users browsers.
(This enables Forms Authentication to work on a web farm)
Therefore there is no way to get a list of logged users etc from standard Forms Authentication.
However Forms Authentication has events that it fires when it Authenticates a user etc. You could update your own list of users in these events – (be careful with locking if you do so)
However as a user will be “logged of” when the cookie is expired by the browsers, you will find it very hard to correctly remove all logged of users at the correct time from your list.
You may be better of stored the time you last saw each users and then having a list of users you have seen in say the last 5 minutes. E.g keep a list of active users.
I used Session_Start and Session_End under Global.aspx. it works most of times except the user close his/her browser. the server side needs to wait for the session expired to remove the user.
My asp.net mvc site needs some kind of authorization but it is rather different than the usual concept of users and thus membership.
It will be used more for preferences then for authentication actually. Accounts without any password should be possible (and will initially be the only type) and an account can also be used by multiple users at once. Depending on the user group it could be for example that all users of a certain region get a shared account.
This is a decision from the client('s marketing division) and is not up for discussion.
A certain landing page takes (only) a userId in the url that will load up an account which in turn has some preferences linked to it that can be used throughout the rest of the site.
If a user doesn't start at the landing page or the sent accountId doesn't match a record in the system, he/she will be assigned the default account that has default preferences.
I was thinking of not re-inventing the wheel (somebody should find a new expression for this) and use the asp.net Membership system.
But the whole system is based around required passwords, email and single sessions per user, which are all things I can't provide.
Because the situation is a bit unconventional I thought a custom MembershipProvider etc would be in place. But it seems the gist of this is inheriting from the regular Membership classes. The methods of these classes all require things I am not needing.
Any suggestions
You could use the standard Membership provider and using the Built in .Validate() method sending the Username and a Password that is "standard" for all accounts without authentication.
Have 2 different User Controls 1 for "Validated Login with Password" and one for "Share Account without password", each uses Membership-login but the latter needs to have a bit set on the field of the member that says "Public Account = True / 1 "
Good luck, seems like a fun project, would be cool to see the outcome ;)
By the way, you don't need to share the session, or you could, just stored the session in the database and map the session to a user instead of a cookie, might work?
As requested i'll elaborate on different user controls. Briefly i would have 2 Controls, one maybe called GlobalLogin and one called UserLogin, where GlobalLogin displays a Form which only has the Username, when submitted this will trigger a function that uses, as i stated before, a function which calls the Validate method in the Membership provider, with a pre-set password.
As a reflection, see all "Not logged in with password"-users as anonymous and treat them the same way, the only thing that is different is that they can access user-specific areas. This control also needs to check that a certain field in the database is set, such as a "Allows Globally Used Account Without Password"-field, where in this case, the bit / boolean needs to be true for this login to be accepted.
Now to the other part, the Control which handles Password Protected Accounts, this requires both Username & Password and this calls the Validate with these settings. Now, remember that when logged in with password, you can change your password, this SHOULD NOT be possible with a Global Account, because then your global password wouldnt work :)
There is detailed information on the Membership Provider at http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx. Basically you need to create new provider, or derive from the existing, and overload the ValidateUser method to always return true.