我们有一个现有的工作系统,我被要求改变向用户提供“权限”的当前逻辑。目前的逻辑不太合适,就性能而言,它太慢了。
目前,我们有25个表,还有更多,我们有110个系统用户。有些是管理员,有些是具有特定权限的简单用户。我们在我们的系统中使用M-V-C实体框架代码第一种方法。
对于每个表,我们有5个复选框,如第一个复选框,用于授予访问页面的权限,第二个用于创建数据,第三个用于读取数据,第四个用于更新数据,第五个用于删除数据。
现在所有这些权限都在一个用户表中,因此在User表中总共有125列。 25个表格x 5个复选框= 125列。
因此,当我们注册用户时,我们可以选择权限,例如user1
只能从国家/地区表中读取国家/地区记录,只能从城市表中添加或编辑城市,只能从宗教表中删除宗教信息。
另外,系统有125种不同的角色。例如CountryCreate
,CountryDelete
,CityCreate
,CityDelete
等等。
在用户注册期间,系统会根据检查的值将不同的角色关联到用户。因此,假设管理员想要向用户提供70个权限,则70个角色将与该特定用户相关联,因为有许多用户需要数千个UserRoles
。如果用户具有特定角色,则创建角色以检入视图,然后显示特定功能,例如国家创建,否则不显示。
应用程序大多数时间都停止工作。因为每个用户都有很多角色和复选框。
我是该项目的新手,第一项工作是更改权限逻辑。实现它的最佳方法是什么?
if (model.countryRead == true)
{
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
userManager.AddToRole(user.Id, "countryRead");
}
所以,像这样我们有125 if statements
,它只适用于Register。在编辑中,如果复选框为false,我们还会else statements
从角色中删除。另外,我们在用户模型中有125个属性。
解决此问题的最佳方法是什么?
答案 0 :(得分:1)
您可以遵循以下方法:
您已拥有User
和Role
型号。你只需要另一种具有这种结构的模型:
public enum Actions
{
Insert,
Delete,
Update,
GetOne,
GetAll
}
public enum Services
{
Country,
Category,
Product,
Warehouse
}
public class UserAccess
{
public int Id { get; set; }
public ApplicationRole Role { get; set; }
public string Title { get; set; }
public Actions Action { get; set; }
public Services Service { get; set; }
}
使用此模型,您可以定义无限访问。
Users
有Roles
每个Role
都可以有很多UserAccess
。
之后,您必须像125 if statements
一样手动检查或更好地使用它,如果您使用的是Web API,我建议您使用:
首先,您必须从AuthorizeAttribute
类继承,并使用您的访问模型(例如Users
,Roles
和UserAccesses
进行自定义,并且您必须覆盖OnAuthorization
方法如:
public class ServiceAuthorize : AuthorizeAttribute
{
public ServiceAuthorize(Actions action, params Services[] services)
{
this.action = action;
this.services = services.ToList();
}
private Actions action { get; set; }
private List<Services> services { get; set; }
public override void OnAuthorization(HttpActionContext actionContext)
{
// check the user's roles here
// if the user don't have needed role or access you can reject it with this code
if (Unauthorized)
{
actionContext.Response = actionContext.Request.CreateResponse(
HttpStatusCode.Unauthorized,
new Dictionary<string, string> {
{ HttpStatusCode.Unauthorized.ToString(), ((int)HttpStatusCode.Unauthorized).ToString() }
}
);
}
}
}
然后,您必须在Web API中使用此Controllers
或Actions
上方的此属性:
public class CountryController : ApiController
{
[ServiceAuthorize(new List<Actions>() { Actions.GetAll }, new List<Services>() { Services.Country })]
public string GetCountries()
{
}
[ServiceAuthorize(new List<Actions>() { Actions.Insert }, new List<Services>() { Services.Country })]
public string AddCountry(Country country)
{
}
}
我希望它会有所帮助。
答案 1 :(得分:0)
如果不了解您的项目结构是什么样的(或实际上存在瓶颈),提供建议很困难,但为了帮助解决性能问题,您可能至少要做5件事:
boolean
字段获取权限,而是使用单个按位int
字段,并将值转换为UI上的5个复选框。例如,1=access;2=create;4=read;8=update;16=delete
,因此如果字段的值为13,则用户将具有访问权限,读取权限和更新权(1 + 4 + 8 = 13)。System.Runtime.Caching.MemoryCache
在内存中缓存权限(和/或角色),从而显着提高性能。 不确定为什么客户&#34;想要表&#34;。也许他们想要数据(已经作为角色存在),这就是你解释它的方式。您的首选应该是消除数据重复并只使用角色(因为MVC可以随时使用角色)。
如果不可能,那么这就是你可以做的事情
UserID | Table (string) | Permission (int)
---------------------------------------------------
1 | Table1 | 13
1 | Table2 | 17
2 | Table5 | 3
请记住,控制&#34;权限&#34;的是您的应用程序,而不是数据实际存储的方式。但是可维护的数据库只会将数据存储在一个地方,让应用程序处理如何使用,显示和更新数据。