Authorization/Roles in MVC5 - c#

I'm having trouble using authorization/roles in MVC5 (VS2013).
Authentication works pretty much out of the box (that's to say just by using Visual Studio to create the default MVC project). I change the DefaultConnection connection string to a valid (but non-existent) database. I then register a new user and the database is automatically created, with tables such as AspNetUsers and AspNetRoles.
However, I can't seem to do anything with roles. The first thing to do seemed to be to add a role with C# code like:
Roles.CreateRole("Admin");
I get an exception with the message:
'The Role Manager feature has not been enabled.'
I enable it in web.config with:
<roleManager enabled="true"/>
And now get the exception:
'Unable to connect to SQL Server database.'
This used to work very easily with System.Web.Security.SqlRoleProvider, but not with the new provider that comes as default with MVC5. There are lots of very complex articles on this, but it seems to me that it is something so essential and straightforward that there must be a simple way to get it working.
Many thanks for any help.

I've solved this now. It turns out that the Roles class is completely irrelevant to role management in MVC5, at least in terms of the out-of-the-box configuration.
The Roles class and Membership class are still there, with the Provider configured to SqlMembershipProvider.
However, this is NOT the provider used by the AccountController, which does not use the Membership class at all; it uses Microsoft.AspNet.Identity.UserManager.
While the generated AccountController provides plenty of examples of using UserManager, it does nothing related to roles.
The equivalent class for Roles is Microsoft.AspNet.Identity.RoleManager. There is full documentation for this in MSDN

I suggest referring to this article as it shows how you can create roles. Once you've created whatever roles are required, you can use the UserManager.AddToRole or UserManager.AddToRoleAsync method to add a user to a particular role.

Related

Forms Authentication — Where are roles stored?

Where are the roles below stored?
Roles.AddUserToRole(user.UserName, "customer");
Roles.IsUserInRole(user.UserName, "admin");
If I add a user to a role using the code then the membership persists. I cant see a built in database in my project and I have not manually specified a database. Am I going mad?
Information about role storage may be picked from web.config
This db might have been created for you by asp.net itself, and is called
aspnetdb
Please look at this as well:
https://msdn.microsoft.com/en-us/library/system.web.security.roles(v=vs.110).aspx

connecting an existing database entity for authentication using NHibernate Identity and MVC AspNet.Identity

I successfully incorporated NHibernate to connect to my MySQL database. I am using the premade authentication in the MVC starter application. Now I’m using this:
https://github.com/nhibernate/NHibernate.AspNet.Identity
to remove entity framework from the application and supplement NHibernate.AspNet.Identity instead. I manage to get the errors down to about 4 and I’m left with an error about ApplicationDbContext in IdentityConfig.cs.
This is because in the instructions it said to "Remove the ApplicationDbContext class completely." But it doesn’t say what to do with it. Because so much of the code is using ApplicationDbContext so a lot of things break.
My main problem or main question is. How to simply check the of the username and password that was input into a form exists in my database and if so, then set IsAuthenticated to true?
The answer was to override/intercept entity and making custom classes to check inputs against the mapped data.

Custom User and Roles with ASP.NET MVC3

I have a ASP.NET MVC site with a CAS server set up as the authentication type. I also have a separate database with a Users table and a Roles table (with a User being related to one or more roles). A User is only able to log into the system if the Username is both in the User table and on the CAS system. I have this solution working.
My problem is i now need some form of trigger on User.IsAuthenticated so i can track the current User (from my database), without the possibility that i am trying to allow tracking of a User that has logged out. What I've been thinking is i need to add the User to the HttpContext but i am not sure how to trigger the clearing of the User if the CAS session times out or if the User Logs out.
I also wish to have some functionality such as User.IsInRole (again using my database, not ASP.NET) but am not sure how to go about implementing this. I suppose if i can successfully add the User to the HttpContext then a IsInRole method would simply be a User.Roles.Contains(string role) method but how can that then be used if i wish, for example, to use a method with the DataAnnotation [Authorize(role = "ExampleRole")].
I have looked at questions such as How do I create a custom membership provider for ASP.NET MVC 2? but this doesn't work for me (possibly to do with me using the CAS authentication?)
Any guidance or background reading would be appreciated as i'm really not sure where i should even start. I have read up on GenericPrinciple, IPrinciple and IIdentity but I'm struggling to see how i can apply them to my current project.
Ended up with a custom Authorise Attribute that uses the CAS logon to check the user exists in my database. It also checks the roles of that user. I also used a static class to save the current user in the session with a logout method that abandons the session when the user logs out.
I have kind of a two parter for you. This link does a really good job of explaining how to replace the HttpContext User with your own object: http://bradygaster.com/custom-authentication-with-mvc-3.0
His approach uses MVC filters, but you can also catch the Authentication event in the Global.asax file. Using the forms system with your own implementation can be trivial or not depending on what you're doing, but it boils down to calling FormsAuthentication.SetAuthCookie and .SignOut, amidst your own logic.
public static void FormsLogin(this User user, bool persist)
{
FormsAuthentication.SetAuthCookie(user.DisplayName, persist);
user.AddHistory("Login event.", HistoryType.Login, "SYSTEM");
Users.OnUserLogin(user);
SetLastActivity(user);
}
public static void FormsLogout(this User user)
{
FormsAuthentication.SignOut();
}
Lastly, once you've got the login stuff working out, you can use your own more complex permission system by making a custom Auth Attribute. I remember piecing this together from some other answers and articles but I can't seem to find the sources at the moment, I will try and edit with sources for credit where it's due, if I find them. For now, all I can offer is this gist which offers up one of the attributes I use: https://gist.github.com/1959509
Keep in mind the only really relevant part there is the override of OnAuthorization, which does the actual work.

Where to stick the configuration of Custom Provider in ASP.NET that implements ProviderBase?

I am trying to figure out a small dillema. I have a piece of functionality that is not supported by the SqlMembership, SqlRole, and SqlProfile providers. The requirements call for using the EF, and also multiple custom features within both the Membership and Role providers.
More over I have the need to add a 4th provider to the mix - One that manages User - to - group membership.
So the question here is:
Add the code for group membership in the Role provider.
-- or --
Add the code for group membership to its own GroupProvider inheriting directly from ProviderBase.
I am leaning more towards #2, however there are a few considerations to iron out:
How to provide configuration settings to the GroupProvider? - I know i can potentially use a custom section in my web.config, however I wanted to add it under the <system.web> section along side the Role, Membership, and Profile providers.
When in the execution life-cycle of the provider do the public override void Initialize(string name, NameValueCollection config) fires? What causes this to be executed?
Thanks,
Martin
Well, i couldn't find any info on this so I decided to stick my custom code into the RoleProvider. Accessing the custom functions of the RoleProvider is as simple as:
string providerName = "MyProvider";
CustomRolesProvider provider = Roles.Providers[providerName] as CustomRolesProvider;
Whenever the provider is accessed it fires the Initialize event if it is not yet initialized - which reads the config settings from the Web.Config under the System.Web section

ASP.NET MVC authentication using custom database instead of ASPNETDB?

I already have a User table in my primary application database with an email address (which will act as the user name) and a password. I would like to authenticate using my database instead of the default authentication database (ASPNETDB).
Questions:
Is this a bad idea? Is it a huge can of worms to use my own DB for authentication?
How much work am I adding by doing this? I already have code for hashing the password and a query that will check if the email and password match the DB. So, I wouldn't be starting from scratch.
What would I need to do to use my database instead of ASPNETDB? I'm hoping this can be described in a few simple steps, but if not, could you point me to good source?
Update
I'm still looking for a little more detail here on my third question. Do I need to write my own MembershipProvider? What changes do I need to make to my web.config file? Will the [Authorize] attribute still work if I write my own solution? Can I use the automatically-generated AccountController with some minor modifications or do I basically need to rewrite the account controller from scratch?
It's quite simple, you need to derrive MembershipProvider and implement the ValidateUser method. Take a look at this post. I'm using custom membership provider with Postgres and MVC just fine.
I'll answer your updated questions:
Do I need to write my own MembershipProvider?
If you (a) want to continue using Forms Authentication, and (b) have an authorization table structure that doesn't follow the same conventions as the ASPNETDB, then yes. If you don't need FormsAuth (see below), then you can do away with the MembershipProvider entirely, but I wouldn't recommend it. Or, if you're using the exact same security tables as ASPNETDB but just want to point it to a different database, you can continue using the default provider and simply change its configuration.
What changes do I need to make to my web.config file?
If you are using your own custom MembershipProvider, then you need to register it in the <providers> section of the <membership> element and change the defaultProvider property. If you are using the standard AspNetSqlProvider then you probably just need to change the connection string.
Will the [Authorize] attribute still work if I write my own solution?
Yes, if you stick to Forms Authentication (either use the AspNetSqlProvider or write and register your own membership provider). No, if you abandon Forms Authentication (again, not recommended).
Can I use the automatically-generated AccountController with some minor modifications or do I basically need to rewrite the account controller from scratch?
You should rewrite the AccountController anyway - don't leave demo code in a production app. But if you must - yes, the AccountController will work under the same conditions as above.
No. And I would suspect most people do not trust that cruddy mechanism
Not much at all, especially since you have the table already.
Take a look at this for example: http://forums.asp.net/t/1250726.aspx
Hi ,
Just follow these simple steps :
First, you can delete the .mdf file in App_Data folder. Since we don’t need any of these tables.Then, we need to update the default connection string in the web.config to point to our database.
<connectionStrings>
<add name=”DefaultConnection” connectionString=”Data Source=SERVER\INSTANCENAME;Initial Catalog=DBNAME;Integrated Security=True” providerName=”System.Data.SqlClient” />
</connectionStrings>
Third, Open Nuget Package Manager and write the following commands:
Enable-Migrations
Add-Migration Init
Update-Database
Check out your database, all ASP.NET membership tables with Prefix Asp have been create and then you can test it out by running your application and execute membership actions such as Signing up or Signing in to your application.
Created tables after running above commands:
AspNetRoles
AspNetUserClaims
AspNetUserLogins
AspNetUserRoles
AspNetUsers
__MigrationHistory
Source : https://blogs.msmvps.com/marafa/2014/06/13/how-to-create-asp-net-mvc-authentication-tables-in-an-existing-database/
We're doing exactly this in one of our applications, and find it quite simple. We have an authentication service (called from the controller) that handles the mechanics of hashing the entered password to see if it is a match, then simply returns a bool for a method we call "IsValidLogon".
In our case, the purpose was to keep the management of what should be a pretty trivial task as lightweight as possible.
We bascially ignored ASPNETDB entirely. If we get a valid response from our user/password check, we simply call the standard FormsAuthentication.RedirectFromLoginPage(username, createCookieBool);
Hope that helps.
just building the same, so answer to 1 must be NO :)
I'm using the standard asp.net forms authentication, where i use the FormsAuthentication.RedirectFromLoginPage(username, createCookieBool) method to log a user in.
I gave a user a unique guid (you can use any other user id) and i'm storing it in the UserName parameter along with the username (to display on the masterpage: Html.Encode(Page.User.Identity.Name.Split("|".ToCharArray())[1]))
In each controller/method in which i must know which user is logged on (via User.Identity.Name, split the string and get the userguid).
Also i decorate those routines with the [Authorize] attribute.

Categories