asp.net mvc,多个CustomAuthorize角色提供程序

时间:2012-11-13 09:30:16

标签: asp.net-mvc roleprovider custom-authentication

我试图将我的应用程序锁定到每个方法,用户和管理员可以看到整个控制器,但只有管理员才能创建,删除和编辑。

我创建了一个CustomAuthorize类来保存方法:

 public class CustomAuthorize : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            Debug.WriteLine("Show me the filterContext " + filterContext);
            if (filterContext.Result is HttpUnauthorizedResult)
            {
                Debug.WriteLine("Why is this going to the redirect to AccessDenied?");
                filterContext.Result = new RedirectResult("~/AccessDenied/Index");
            }
        }
    }

我的RoleProvider类:

namespace Office.WebUI.Security {
    public class OfficeRoleProvider : RoleProvider
    {

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            throw new NotImplementedException();
        }

        public override string[] GetRolesForUser(string username)
        {
            Debug.WriteLine("Get the username" + username);
            using (EFDbContext db = new EFDbContext()) >           
            {
                User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, >stringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));
                //User user = db.TaskPrivilege.FirstOrDefault(u => >u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));

                if (user != null)
                {
                    var roles = from ur in user.UserRoles
                                from r in db.Roles
                                where user.role.RoleID == r.RoleID
                                //where ur.RoleID == r.RoleID
                                select r.Name;
                    if (roles != null)
                        return roles.ToArray();
                    else
                        return new string[] { }; ;
                }
                else
                {
                    return new string[] { }; ;
                }
            }
        }

        public override string[] GetUsersInRole(string roleName)
        {
           throw new NotImplementedException();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            Debug.WriteLine("The username is " + username + " And the Role it is using is >" + roleName);
            using (EFDbContext db = new EFDbContext())
            {
                User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));

                if (user != null)
                {
                    var roles = from ur in user.UserRoles
                                from r in db.Roles
                                where user.role.RoleID == r.RoleID
                                //where ur.RoleID == r.RoleID
                                select r.Name;
                    if (user != null)
                        return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));
                    else
                        return false;
                }
                else
                {
                    return false;
                }
            }
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            throw new NotImplementedException();
        }
    }

}

在我的数据库中,我有一个角色表,其中包含Role和RoleID作为列,其中2个值为Administrator,用户为角色,其中roleID为PK,1 = Administrator& 2 =用户。 另一个名为Users的表,包含UserID,Username和role_RoleID

当我将用户指定为role_RoleID为1(管理员)并使用

锁定控制器时
  

[CustomAuthorize(Roles =“Administrator”]

这很有效。

当我指定role_RoldID = 2并使用以下方法锁定时:

  

[CustomAuthorize(Roles =“User”]

这不起作用?

另一个问题是,如何为控制器分配2个角色?,然后我想将每个方法锁定为1个用户角色。

希望这是有道理的,我希望有人可以帮助我。

由于

史蒂芬

基本上我有一个控制器,我已经把它 [CustomAuthorize(Roles = "Administrators, Support")] 锁定它,这样两个角色都可以看到控制器。

然后我创建/删除并编辑我拥有的方法:

[CustomAuthorize(Roles = "Administrators")]

所以我基本上想要将整个控制器显示给两个角色,但只有管理员才能创建/编辑/删除。

当我在user table = 2(User)中分配一个roleID时,整个应用程序会中断该用户。分配RoldID = 1(管理员)它适用于所有被分配roldID 1的人。

目前我有方法

public override string[] GetRolesForUser(string username)
{

    using (EFDbContext db = new EFDbContext())  

    {
        User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));


        if (user != null)
        {
            var roles = from ur in user.UserRoles
                        from r in db.Roles
                        where user.role.RoleID == r.RoleID

                        select r.Name;
            if (roles != null)
                return roles.ToArray();
            else
                return new string[] { }; ;
        }
        else
        {
            return new string[] { }; ;
        }
    }
}


> public override bool IsUserInRole(string username, string roleName)
>         {
>             
>             using (EFDbContext db = new EFDbContext())
>             {
>                 User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase)
> || u.Email.Equals(username,
> StringComparison.CurrentCultureIgnoreCase));
> 
>                 if (user != null)
>                 {
>                     var roles = from ur in user.UserRoles
>                                 from r in db.Roles
>                                 where user.role.RoleID == r.RoleID
>                                 //where ur.RoleID == r.RoleID
>                                 select r.Name;
>                     if (user != null)
>                         return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));
>                     else
>                         return false;
>                 }
>                 else
>                 {
>                     return false;
>                 }
>             }
>         }

我知道我必须更改IsUserInRole方法,以便它处理一个像这样的数组参数,public override bool IsUserInRole(string username, string[] roleName)

但是不知道如何在linq中处理它,主要是在IsUserInRole方法中:

return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));

目前它在GetRolesForUser方法失败,在我认为的where子句

  

其中user.role.RoleID == r.RoleID

错误信息显示如下:

已经有一个与此命令关联的打开DataReader,必须先关闭它。 描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.InvalidOperationException:已经有一个与此命令关联的打开的DataReader,必须先关闭它。

来源错误:

第66行:var roles = from ur in user.UserRoles第67行:来自db.Roles第68行:其中user.role.RoleID == r.RoleID

由于

1 个答案:

答案 0 :(得分:2)

可以这样做多个角色: [CustomAuthorize(Roles = "Administrator, User")] 但看到你写过这段代码,我觉得你已经知道了吗?

如果您只想让Users无法进入创建/编辑/删除功能,为什么不使用默认授权功能?意思是,将[CustomAuthorize(Roles = "Administrator")]置于编辑/创建/删除之上,将[CustomAuthorize(Roles = "Administrator, User")]置于其他任何内容之上......

我猜测授权会调用IsUserInRole吗?此方法应采用string [] roleName数组,而不仅仅是字符串。

编辑: 改变

                        var roles = from ur in user.UserRoles
                        from r in db.Roles
                       where user.role.RoleID == r.RoleID
                        //where ur.RoleID == r.RoleID
                       select r.Name;

var roles = user.UserRoles.select(q=>q.Roles.Name);
相关问题