How to override IsInRole method in MVC 4 Custom Membership? - asp.net-mvc

I'm very new to MVC. I'm doing a Custom Membership asp.net MVC4. Above are the Table & data i have created. I try to override isinrole method but its not working.Below is the sample code & i don't know where to edit it.
public override bool IsUserInRole(string userName, string roleName)
{
User user = repository.GetUser(userName);
Role role = repository.GetRole(roleName);
if (!repository.UserExists(user))
return false;
if (!repository.RoleExists(role))
return false;
return user.Name == role.Name;
}
Now i need to get list of roles for a user from UserInRole Table but the this table is not visible.I have to check whether the User role are matching with User.IsInRole("Administrator") .Hope anybody can guide me.Thank u in advance.

It's not working because you're comparing the role name with the user name ("a" != "Administrator"). You need something more like this.
public override bool IsUserInRole(string userName, string roleName)
{
User user = repository.GetUser(userName);
Role role = repository.GetRole(roleName);
if (!repository.UserExists(user))
return false;
if (!repository.RoleExists(role))
return false;
return user.Role.ID == role.ID;
}
It may differ depending on how your entities are setup though.

Related

Permission Based Authorization with ASP.Net Identity 2

I'm working on a ASP.Net MVC 5 app and using ASP.Net identity 2, and need to authorize users based on roles and permissions. roles and permissions is not related to each other. for example, to access "action1" action method,( "admin" role ) or ( combination of "role1" and "permission1" ) must exist for him, but other users that is not in "admin" role or combination of ( "role1" and "permission1") is not true for theirs, don't allow to access that action method.
how i can do this scenario?
do claims based authorization useful in this manner?
or i must implement Permission entity and custom AuthorizeAttribute? if true how?
best regards
Check out the ResourceAuthorize attribute in the Thinktecture.IdentityModel.Owin.ResourceAuthorization.Mvc package.
This attribute authorizes a user based on an action (e.g. read) and a resource (e.g. contact details). You can then base whether or not they are allowed to perform that action on a resource based on a claim (e.g. their presence in a role).
See here for a good example.
Might not be exactly what you are looking for, but you can take inspiration and implement your own authorization attribute using similar logic.
This is custom made Authorize which checks permission from database.
For example you have 3 bools for permission Account,Clients,Configuration
and you want to restrict user based on them.
you can add even two permission on one action, for example you have a method which can be accessed by Account and Client permission than you can add following line
Modify this to use roles with permissions in this, this is the easiest and best way to handle it.
[PermissionBasedAuthorize("Client, Account")]
This method below is which check the bools from database.
public class PermissionBasedAuthorize : AuthorizeAttribute
{
private List<string> screen { get; set; }
public PermissionBasedAuthorize(string ScreenNames)
{
if (!string.IsNullOrEmpty(ScreenNames))
screen = ScreenNames.Split(',').ToList();
}
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
var UserId = HttpContext.Current.User.Identity.GetUserId();
ApplicationContext db = new ApplicationContext();
var Permissions = db.Permissions.Find(UserId);
if (screen == null || screen.Count() == 0)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
bool IsAllowed = false;
foreach (var item in screen)
foreach (var property in Permissions.GetType().GetProperties())
{
if (property.Name.ToLower().Equals(item.ToLower()))
{
bool Value = (bool)property.GetValue(Permissions, null);
if (Value)
{
IsAllowed = true;
}
break;
}
}
if (!IsAllowed)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
}
}
I implemented a Permission-based extension for Microsoft Identity 2 membership system. But in this extension, permissions and roles are related together. there is a many-to-many relation between them. Also you can have a complex authentication with combination of roles and permissions. I suppose it can help you to do permission based authentication.
You can do permission authentication in two ways:
First approach:
// GET: /Manage/Index
[AuthorizePermission(Name = "Show_Management", Description = "Show the Management Page.")]
public async Task<ActionResult> Index(ManageMessageId? message)
{
//...
}
Second approach:
// GET: /Manage/Users
public async Task<ActionResult> Users()
{
if (await HttpContext.AuthorizePermission(name: "AllUsers_Management", description: "Edit all of the users information."))
{
return View(db.GetAllUsers());
}
else if (await HttpContext.AuthorizePermission(name: "UnConfirmedUsers_Management", description: "Edit unconfirmed users information."))
{
return View(db.GetUnConfirmedUsers());
}
else
{
return View(new List<User>());
}
}
Also it's an open source and free extension and you can access to the repository here.

MVC 4 - RoleProvider to manage authenticated users permissions with different scopes

Here is my problem with my MVC 4 Internet project using Forms Authentication.
Lets say i have hotels and i want the authorized users accessing each under different roles.
So the user logs in. Then from a dropdownlist selects the target Hotel and the application´s security responds accordingly.
I would need something like [Authorize(Roles = "Administrator")] but only in that hotel scope.
My first aproach was inheriting from AuthorizeAttribute and override AuthorizeCore like is shown in this thread
From there I could get the HttpContext.Session["HotelId"] and query a UserRolesInHotel table. That said, I should have my own roles table with a structure similiar to UserId, RoleId, HotelId. So SimpleRolePrivider comes short to this task and i would be forced to create a CustomeRoleProvider. RoleProvider Methods don´t handle extra params as I need like HotelId when adding a new role to a user.
For clarification:
User A logs in with user/password ->OK (SimpleMembershipProvider)
Authenticated User A selects Hotel 1 -> User A is an "Administrator" for Hotel 1.
Authenticated User A change to Hotel 2 -> User A is a "User" in Hotel 2
I can have any number of hotels.
User A -> Hotel 1 -> { "Administrator", "User"}
User A -> Hotel 2 -> { "User" }
User A -> Hotel 3 -> { "Owner" }
User A -> Hotel 4 -> { "Administrator" }
The list of roles is always the same.
I´ve been struggling with this implementation for a couple of days and i couldn´t come up with a pratical solution.
Any thougths would be much appreciated.
Thanks!
This is what I did:
Added a DefaultBuildingId to the user profile.
Then I created a CustomRoleProvider and overrided GetRolesForUser method like this
public override string[] GetRolesForUser(string userName)
{
if (HttpContext.Current.Session != null)
{
var user = _userRepository.GetByName(userName);
if (!user.IsActive)
{
throw new ApplicationException(string.Format("some message {0}", userName));
}
if (HttpContext.Current.Session["BuildingId"] == null)
{
var building = _buildingRepository.Get(user.DefaultBuildingId);
if (building == null)
{
throw new ApplicationException("error message");
}
HttpContext.Current.Session["BuildingId"] = building.BuildingId;
}
int buildingId = Convert.ToInt32(HttpContext.Current.Session["BuildingId"]);
return _userRepository.GetRolesForUserInBuilding(user.UserId, buildingId).ToArray();
}
throw new ApplicationException("error message.");
}
Added a custom AuthorizeAttribute
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
var repo = UnityManager.Resolve<IUserRepository>();
var buildingId = (int)httpContext.Session["BuildingId"];
var userName = httpContext.User.Identity.Name;
var user = repo.GetByName(userName);
var userRolesInBuilding = repo.GetRolesForUserInBuilding(user.UserId, buildingId);
foreach (var role in Roles.Split(','))
{
if (userRolesInBuilding.Contains(role.Trim()))
{
return true;
}
}
return false;
}
And finally this is how to use it at controller or action level.
[BuildingAthorize(Roles = "Administrators")]
I also added a ddl to the layout to let the user change the building and set the new BuildingId overriding the value at the session/db. This way a user can work in different Hotels during the same session and only access areas and functionality he has for that particular hotel.

MVC 3 - access for specific user only

In my web application registered users can add new content and edit it later. I want only the content's author to be able to edit it. Is there any smart way of doing this other than manually writing code in all the action methods that checks if the logged user is the same as the author? Any attribute that I could use for the whole controller?
Any attribute that I could use for the whole controller?
Yes, you could extend the Authorize attribute with a custom one:
public class AuthorizeAuthorAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
// the user is either not authenticated or
// not in roles => no need to continue any further
return false;
}
// get the currently logged on user
var username = httpContext.User.Identity.Name;
// get the id of the article that he is trying to manipulate
// from the route data (this assumes that the id is passed as a route
// data parameter: /foo/edit/123). If this is not the case and you
// are using query string parameters you could fetch the id using the Request
var id = httpContext.Request.RequestContext.RouteData.Values["id"] as string;
// Now that we have the current user and the id of the article he
// is trying to manipualte all that's left is go ahead and look in
// our database to see if this user is the owner of the article
return IsUserOwnerOfArticle(username, id);
}
private bool IsUserOwnerOfArticle(string username, string articleId)
{
throw new NotImplementedException();
}
}
and then:
[HttpPost]
[AuthorizeAuthor]
public ActionResult Edit(int id)
{
... perform the edit
}
I would:
Save the db.aspnet_Users columm UserId (Guid) against the content record
Write an extension method for your content model which verifies the current users Guid against the saved contents User Guid
I would write some code that overrides this functionality for your Admin logins (I would create an Admin Role).

Update User Entity Framework

I am writing an asp.net membership provider using Entity code first and I need some help understanding how to Update the MembershipUser object.
The UpdateUsert(MembershipUser user) override method needs to be implemented and consists of a MembershipUser parameter.
The following code does not work and I am not sure how to tie the MembershipDBContext with the supplied membership user so that the user is updated. Thanks for the help.
public override void UpdateUser(MembershipUser user)
{
MembershipDBModel userToUpdate = _getMembershipDBModelUser(user.UserName);
userToUpdate.IsLockedOut = user.IsLockedOut;
using (MembershipDBContext db = new MembershipDBContext())
{
db.SaveChanges();
}
}
Why not use the built in functionality for the MembershipProvider?
MembershipUser user = Membership.GetUser();
user.IsApproved = false;
Membership.UpdateUser(user);

Implement custom "ValidateUser" in MembershipProvider

I am implementing a custom MembershipProvider and I am trying to get the ValidateUser method to validate against my Profiles table in SQL Server. This table has columns called UserName and Password.
public override bool ValidateUser(string username, string password)
{
??? what to do here???
}
FYI, I am using MVC3 & EF 4.1 Code First.
Thanks
Paul
If you're using EF 4.1, you will have some kind of a DbContext object that contains the DbSet for your Profiles table - right?
So in that case, use this:
public override bool ValidateUser(string username, string password)
{
using(DbContext yourCtx = new DbContext())
{
// from your "Profiles" DbSet, retrieve that single entry which
// matches the username/password being passed in
var profile = (from p in yourCtx.Profiles
where p.UserName == username && p.Password == password
select p).SingleOrDefault();
// if that query returns a "Profile" (is != null), then your
// username/password combo is valid - otherwise, it's not valid
return (profile != null);
}
}

Resources