权限管理
权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少。权限管理几乎出现在任何系统里面,只要有用户和密码的系统。权限管理还是比较复杂的,有的固定到某个模块,某个操作,甚至是某个按钮,总之想要做好一个权限管理,真的很不容易,一直在探索当中,全当抛砖引玉;看到网上好多关于权限管理的文章,以前也写过简单的文章,今天楼主我也要总结整理一下自己的实现方法,毕竟一千个读者就有一千个哈姆雷特,说说自己的详细实现、基本设计和基本思想希望帮到入门的新人们。
一、基本的数据库表设计
基本的表设计如图,用户表、角色表、模块表、权限表和用户角色关系表、角色模块权限关系表,某个用户的角色(管理员、用户等),然后再去判断对应角色的模块(新闻、文章等)权限(增、删、改、查)。
创建基本权限操作的SQL脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
CREATE
TABLE
[dbo].[Module](
[ID] [
int
] IDENTITY(1,1)
PRIMARY
KEY
NOT
NULL
,
[ModuleKey] [nvarchar](100)
NOT
NULL
,
[ModuleName] [nvarchar](100)
NOT
NULL
,
)
CREATE
TABLE
[dbo].[Permission](
[ID] [
int
] IDENTITY(1,1)
PRIMARY
KEY
NOT
NULL
,
[PermissionKey] [nvarchar](100)
NOT
NULL
,
[PermissionName] [nvarchar](100)
NOT
NULL
,
)
CREATE
TABLE
[dbo].[Role](
[ID] [
int
] IDENTITY(1,1)
PRIMARY
KEY
NOT
NULL
,
[RoleName] [nvarchar](100)
NOT
NULL
,
)
CREATE
TABLE
[dbo].[RoleModulePermission](
[ID] [
int
] IDENTITY(1,1)
PRIMARY
KEY
NOT
NULL
,
[RoleID] [
int
]
NOT
NULL
,
[ModuleID] [
int
]
NOT
NULL
,
[PermissionID] [
int
]
NOT
NULL
,
)
CREATE
TABLE
[dbo].[
User
](
[ID] [
int
] IDENTITY(1,1)
PRIMARY
KEY
NOT
NULL
,
[AccountNum] [nvarchar](100)
NOT
NULL
,
[Pwd] [nvarchar](100)
NOT
NULL
,
[Status] [
int
]
NOT
NULL
,
[LastLoginTime] [datetime]
NOT
NULL
,
[Remark] [nvarchar](100)
NULL
,
)
CREATE
TABLE
[dbo].[UserRole](
[ID] [
int
] IDENTITY(1,1)
PRIMARY
KEY
NOT
NULL
,
[UserID] [
int
]
NOT
NULL
,
[RoleID] [
int
]
NOT
NULL
,
)
|
二、代码中具体的实现
这是一个基类,所有的Controller都继承BaseController,[UserAuthorizeFilter(Order = 999)],每一个Action过滤器都有一个 Order 属性,用来决定Action过滤器在该范围内的执行顺序。Order属性必需是0(默认值)或者更大的整数值。省略Order属性则会给该过滤器的Order值为 -1, 表明为指明顺序。任何一个在同一范围的Action过滤器Order设为 -1 的都将按不确定的顺序执行,单在此之前过滤器有一个特定的顺序。登录的时候是存储的加密的Cookie,会有一个私钥(自己定义)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
[UserAuthorizeFilter(Order = 999)]
public
class
BaseController : Controller
{
public
int
LoginID {
get
;
set
; }
public
string
LoginName {
get
;
set
; }
/// <summary>
/// 是否登录的标志
/// </summary>
/// <returns></returns>
public
bool
IsLogin()
{
if
(NCookieUtil.GetCookie(
"GkqCMSCookie"
) !=
null
)
{
string
cookie_ver = NCookieUtil.GetCookie(
"GkqCMSCookie"
);
string
[] cookieArray = cookie_ver.Split(
'&'
);
int
loginId = cookieArray[1].ToInt();
string
token = cookieArray[0].ObjectToString();
Admin_User user = AdminPermissionRepository.Get(loginId);
if
(user !=
null
)
{
string
tokenKey =
string
.Format(
"{0}{1}{2}{3}"
, user.ID.ObjectToString(), user.AccountNum.ObjectToString(), user.Pwd.ObjectToString(), CommonHelper.SecretSalt);
if
(token == tokenKey)
{
LoginID = user.ID;
LoginName = user.AccountNum;
return
true
;
}
return
false
;
}
return
false
;
}
else
{
return
false
;
}
}
}
|
Filter里面判断用户是否登录cb.IsLogin(),如果登陆验证通过还要验证是否对某个某个Controller对应的Action有操作权限。如果未登录或者发成错误底层会捕获,跳转到登陆页面或者是错误页。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
public
class
UserAuthorizeFilter : System.Web.Mvc.AuthorizeAttribute
{
public
override
void
OnAuthorization(AuthorizationContext filterContext)
{
BaseController cb = filterContext.Controller
as
BaseController;
if
(!cb.IsLogin())
{
SetHttpContext(filterContext, GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult.NotLogin,
"未登录"
);
}
else
{
bool
IsAuthorization = filterContext.Controller.TempData[
"IsAuthorization"
].ToBoolean(
true
);
if
(IsAuthorization)
{
string
controller = filterContext.RouteData.Values[
"controller"
].ObjectToString();
string
action = filterContext.RouteData.Values[
"action"
].ObjectToString();
if
(!AdminPermissionRepository.IsPowerPage(cb.LoginID,controller, action))
{
SetHttpContext(filterContext, GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult.NoAccess,
"您没有权限执行此操作"
);
}
}
}
}
private
void
SetHttpContext(AuthorizationContext filterContext, GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult result,
string
msg)
{
if
(filterContext.HttpContext.Request.IsAjaxRequest())
{
var
data =
new
{ Result = (
int
)result, Msg = msg };
filterContext.Result =
new
JsonpResult() { Data = data, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
else
{
if
(result == GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult.NotLogin)
{
filterContext.Result =
new
RedirectResult(
string
.Format(
"/Login/Index?ReturnUrl={0}"
, filterContext.HttpContext.Request.Url.OriginalString));
}
else
{
filterContext.Controller.ViewData[
"ErrorMessage"
] = msg;
filterContext.Result =
new
ViewResult() { ViewName =
"Error"
, ViewData = filterContext.Controller.ViewData };
}
}
}
}
|
用户的ID判断角色,然后把角色去查是否有这个权限,如果有进入,对应的controller 和action,如果没有则没权限。具体实现方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public
static
bool
IsPowerPage(
int
loginID,
string
Moudle,
string
operate)
{
try
{
string
sql =
string
.Format(
@"SELECT COUNT(1)
FROM (
SELECT c.modulekey,
d.permissionkey
FROM (
SELECT *
FROM Admin_userrole
WHERE userid = {0}
) a
LEFT JOIN Admin_RoleModulePermission b
ON a.roleId = b.roleId
LEFT
JOIN Admin_Module c
ON b.moduleId = c.Id
LEFT JOIN Admin_Permission d
ON b.PermissionId = d.Id
) e
WHERE e.moduleKey = '{1}'
AND e.PermissionKey = '{2}'"
, loginID, Moudle, operate);
return
NSqlHelper.ExecuteScalar(NWebConfig.ReadConnectionString(DBCon.SYS_DBCONNSTRING), CommandType.Text, sql,
null
).ToInt() > 0;
}
catch
(Exception ex)
{
log.Error(
"AdminPermissionRepository-IsPowerPage"
, ex);
return
false
;
}
}
|
用户登录成功写入Cookie,然后浏览每个模块判断登录和具体某个模块的权限, 这算是一个最基本简单权限管理,适合新手入门用,