I'm trying to use the Authorize attribute on MVC 4 application,
[Authorize(Roles = "Administrator, Super-User")]
public JsonResult Remove(int id)
{
.
.
.
}
I know that only the roles "Administrator" and "Super-User" roles are authorized to execute the method Remove, but how I can set the role to the actual User of the application?
The answer is - somehow, so that HttpContext.Current.User is set and the IsInRole method returns true.
The easiest way to do this would be to follow one of built-in mechanisms of authentication/authorization: Forms authentication or Windows authentication.
The former requires that the request carries a valid forms cookie issued by the server. The latter requires that the request principal can be authenticated in the domain controller.
You are however free to implement a custom authentication module.
If you are just starting to learn this, probably you'd like to use Forms Authentication for this. Just let your users log in, issue the cookie and the cookie will automatically be carried by subsequent ajax request (assuming your server code is called from within javascript client-side ajax call).
You can Add the current user to a role using
Roles.AddUsersToRole(new string[]{HttpContext.Current.User.Identity.Name}, "Admin");
Roles class is available in System.Web.Security namespace.
if you want to add users and Roles
-Open your solution in Visual Studio
goto project->ASP.NET configuration->Security Tab
You can add a user to roles using a Role Provider.
var rolesProvider = (SimpleRoleProvider)Roles.Provider;
Check the role exists
if (!rolesProvider.RoleExists("SuperUser"))
{
rolesProvider.CreateRole("SuperUser");
}
Check if the user is in the role already, if not, add the user to the role
if (! rolesProvider.IsUserInRole("JohnSmith", "SuperUser"))
{
rolesProvider.AddUsersToRoles(new[] {"JohnSmith"}, new[] {"SuperUser"});
}
Related
I am working on a asp.net website and I am having trouble implementing a custom role provider using forms authentication.
I have a SQL Server database "MyBase" with a "UserRoles" table which contains UserRoleID, EmployeeID, RoleID, and UserName fields. I want to retrieve the roles for a user from this table when users log in using a custom login page (just a couple textboxes, labels, and a button).
I have searched/read several questions, scenarios, and examples but I'm still missing something somewhere so I'm reaching out for some assistance.
What I have done so far:
In web.config:
Set authentication mode to forms
Set membership provider settings
Set role provider settings
I have created the follow custom classes and listed sub/function/properties:
RoleProvider
--GetRolesForUser
--IsUserInRole
--ApplicationName
MembershipProvider
--GetUser
--UpdateUser
--ValidateUser
MembershipUser
In my login button:
I encrypt the user's password.
Call my custom MembershipProviders' ValidateUser MemProv.ValidateUser(txt_username.Text, encrypedPW)which returns true or false correctly.
Call FormsAuthentication.SetAuthCookie(txt_username.Text, False)
Call my custom RoleProvider's GetRolesForUser function: RoleProv.GetRolesForUser(txt_Username.Text) which returns a String() or roles correctly.
When I check my User.Identity, isAuthenticated = false and Name = "".
I'm pretty sure I am missing an implementation of IIdentity and/or IPrincipal, but I don't know where/how to implement them.
So my questions are:
Do I need to go through all of this just to keep my roles in a SQL Server table I created?
Do I need to incorporate IIDentity and IPrincipal? If so, how do I or where do I do that?
Re-create the MyBase database using the ASP.Net IIS Registration tool (Aspnet_regiis.exe). This will create the database necessary to store your membership information - properly.
Here's a link that gives more information: http://msdn.microsoft.com/en-US/library/k6h9cz8h(v=vs.100).ASPX
I created two classes that implement IPrincipal and IIdentity.
In the Principal's IsInRole function I make a call to my custom RoleProvider's IsUserInRole function.
I logged using my custom login page and was redirected to the correct form. The Identity and RolePrincipal both contain the correct information.
ASP.NET 4.5 / C# / SQL 2012
I already have a well defined database with a users table and a roles/permissions column. The column contains a delimited list of roles. I was hoping to use ASP.NET's built in features on the back-end so I can be lazy and use things like the and filter by role. I'd like to read my roles from the database and tell ASP these are the roles my user is in. Custom...but hopefully simple. Here is what I have so far:
//create an identity
GenericIdentity objIdentity = new GenericIdentity("Matt"); //this would actually be the username/email of the newly authenticated user
//get roles for user
string[] strRoles = { "ADW", "USR" }; //this will get read from the database on authentication
//add identity and roles to a principal
GenericPrincipal objPrincipal = new GenericPrincipal(objIdentity, strRoles);
//add to current user
HttpContext.Current.User = objPrincipal;
//add the principal to the current context of the current thread
Thread.CurrentPrincipal = objPrincipal; //not sure what this does, doesn't affect my results/tests
If I execute the code above and then run the following:
Response.Write(User.IsInRole("ADW"));
Response.Write(User.IsInRole("xxx"));
I get a True/False as expected. However, this doesn't persist to the next page. I did a fair amount of reading on custom membership/role providers, but I can't find this specific use case. Most talk about setting up a DB specifically for this task. I also saw mention of the newer Simple Membership, but couldn't get any love from that end either. I'm hoping there is a solution that involves what I'm already doing. I'd love to execute this code when the user authenticates, but be able to reference this user in other pages. I could always call to the database for every page. I'm assuming that would suck, and that's not what the built in provider does.
Thanks all.
You are approaching it from the wrong side. You don't have to create identity and principal manually, assuming you are not creating a custom authentication module.
In any other case, you only choose the persistence mechanism and the corresponding authentication module sets the identity/principal according to the persistence.
A commonly used persistence mechanism is Forms Authentication, where you issue forms cookies. The forms authentication module makes sure the identity/principal is set early in the pipeline and takes the cookie as the source of information.
If you want to replace the cookie by your custom cookie (in other words - replace forms authentication with your own) - you have to think of a way to persist the security info, to the cookie for example.
Note, however, that this is probably not necessary. The very same forms authentication can be used with any custom membership and role providers. This is because these two have different responsibilities - membersip provider is for actual authentication whereas forms authentication module is for persisting the information for consecutive requests.
Edit: to add a role for a user so that it is persisted in the user database:
Roles.AddUsersToRoles( ... );
But first, you'd have to create users in the user database:
Membership.CreateUser( ... );
Note that Roles and Membership are facades for actual role and membership providers. While default providers use the membership database, you can easily create custom providers that persist the information anywhere at the server side.
Using ASP.Net Forms and ASP.Net MVC 3 (combined - we are in process of changing Web Forms to MVC), I have a scenario where a person authenticates (user name / password) but due to a specific condition existing on their account, they are required to change their password before proceeding.
Since the user is already authenticated, is there a global location where I can prevent any access to the portions of the site that require authentication until they enter their new password? I understand that there might have to be 2 locations (one for Web Forms, the other for MVC).
In Application_AuthenticateRequest check for the specific condition. If not met (ie they must change pwd), redirect to the proper page. This should work for MVC and WebForms.
You could have a custom RoleProvider that uses a flag in the user class to determine if the password needs to be changed before validating the role for a user.
I'd put it as a property in the User model (i.e. public bool ChangedPassword {get;set;}). This will be set as False when the user is created, and set as True when the user changes the password. Before any protected action, check if ChangedPassword == True.
I want to redirect people according to their role in the asp.net membership provider. I have some code in 'OnLoggedIn' event on the login page. Here is what I tried so far, and nothing doesn't work:
The code below returns false on the .IsAuthenticated step, it says the user is not authenticated. On which step at the login page the user is authenticated, I thought the 'OnLoggedIn' event is the right place to do this.
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
}
}
}
2nd thing I tried was to get all the roles for the user, but it doesn't return anything, returns empty array of strings, and I checked the database that the role is assigned to that specific user. Here is how I am trying:
string[] userRole = Roles.GetRolesForUser(LoginUser.UserName);
So, my question is how I can get the role on the login page, do I need to check that in some other event or on some other way.
Thanks for your help in advance, Laziale
The first situation won't work because it returns the value of the Request as it came in. Logging in with FormsAuthentication basically just sets a cookie in the Response so that the next Request gets the right User.
The second situation should work though, assuming that LoginUser is the name of your login control.
if you have some predefined set of rules like (SuperAdmin,Admin,User,....) than
you can use a switch case
and according to the authentication level
you can classify/redirect the user accordingly with respective URL
Greg is totally correct. So the question is why the roles are not returned? There could be several reasons depending on how you created the roles on your rolesprovider settings in web.config.
So make sure you roles provider is pointing to the same database you are see the roles.
Also check you are not using different role provider to create roles but accessing it via different one. This can happen if you have more than one roles provider in web.config.
Also check if it isn't the applicationName issue.
If that doesn't help post your web.config roles setting as well as info on how you are creating roles.
I have an existing website using forms authentication with Sql provider. Now i am trying to integrate with another website and use their authentication mechanism. I am already able to validate a user and trying to silently login the user into my application. Here is the code for "silent" login:
if (user != null) // logged in!
{
IPrincipal principal = new MyPrincipal(user);
FormsAuthentication.SetAuthCookie(user.ScreenName, true);
HttpContext.Current.User = principal;
Response.Redirect("~/Default.aspx");
}
and it works with the exception that Forms Authentication overrides the HttpContext.Current.User by the time i make it "default.aspx". Is there a way to bypass forms role and membership providers?
If you are using a custom principal, the custom principal must be established on every request to the web server; it's not persisted. Adding code to reload it in global.asax would resolve it. Others have created an HTTP module to do this too.
HTH.