我试图将我的应用程序锁定到每个方法,用户和管理员可以看到整个控制器,但只有管理员才能创建,删除和编辑。
我创建了一个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
由于
答案 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);