E
eastphoenix
Unregistered / Unconfirmed
GUEST, unregistred user!
小弟刚刚接触实际应用,不知应用程序中的权限管理该如何做,今天下午偶然想到了一个方
案,请各位高手点评一下优缺点,顺便提供几个权限管理的成功方法。谢谢。
建立一个权限表,包括权限等级,函数标志。用户在登录时用自己的用户名和密码登录之后
,在用户表里记录自己的权限等级,以后每次调用函数都检查用户的权限等级和这个函数的
关系。例:
用户表
用户名 密码 权限等级
Liu 123 1
Zhang 234 2
权限和相应函数对照表
权限等级 函数标志
1 Aaa
2 bbb
1 bbb
用户每次调用函数提供自己的用户名(session)函数可能如下:
procedure Aaa(const session, pwd, out isSuccess)
var
procedureID:String;
begin
isSuccess := false;
procedureID := ‘Aaa’;//函数标志,不是函数名,也可以和函数重名。
Select * from权限和相应函数对照表,用户表 where用户名=session and
密码 = pwd and 用户表.权限等级=权限和相应函数对照表. 权限等级
and函数标志=procedureID;
If 记录数=0 then
exit;//如果此用户名所拥有的权限不拥有此函数的使用权
//则退出。
……//否则执行函数。
……
isSuccess := true;
end;
修改权限等级可执行的函数时,只需在表中插入或删除记录即可
为了不让用户了解更多的组件内部函数,可以自己编写一个程序来进行权限表的修改。
优点:权限管理清晰方便。可以在代码级设定权限。
缺点:每个函数调用都要查询数据库,不知是否服务器受得了。
一个改进方法:
组件模块建立一个全局数组,存放每一个函数调用者的权限等级,在初始化时从数据库中提
取并赋值。用户提交自己的权限等级,然后在函数中判断
用户每次调用函数提供自己的权限等级(level)函数可能如下:
procedure Aaa(const level, out isSuccess)
begin
isSuccess := false;
if level <> gloabRight.getRight(Aaa)
//gloabRight.getRight()为一个类成员方法,用于返回函数标志为Aaa的权限等级。
Exit
else
……//执行函数
……
isSuccess := true;
end;
end;
优点:只在模块初始化时读一次数据库,减少了系统额外负担。
缺点:当一个函数标志对应多个权限等级时,需要编码做额外处理,暂时没仔细想怎么做。
无法对用户提供的level做判断,只能假定是合法的,和直接提供session而不提供密码是
一样的。
另一种改进方法:
权限表
权限等级 权限执行码(暂定)
1 111
2 110
3 100
其中权限执行码根据函数表和权限和相应函数对照表生成
函数表
函数名 二进制编码
Aaa 001
Bbb 010
Ccc 100
权限和相应函数对照表
权限等级 函数标志
1 Aaa
1 Bbb
1 Ccc
2 Bbb
2 Ccc
3 Ccc
用户登录后,从数据库中找出他所拥有权限的执行码发给用户,每次用户调用的时候传递一
个执行码,在函数中进行判断
用户每次调用函数提供自己的权限执行码(exeCode)函数可能如下:
procedure Aaa(const exeCode, out isSuccess)
begin
isSuccess := false;
if (exeCode 逻辑与 001) = 0 then
exit
else
……//执行函数
……
isSuccess := true;
end;
优点:用户提供的是一组看上去无意义的二进制数,提高的攻击的难度。
缺点:函数中权限执行码是写死的,而且随着函数的增多,权限执行码会很长。
两种改进方法的结合:
组件模块初始化时从数据库中动态调出每一个函数的二进制编码,然后在函数中用
gloabRight.getRight()来取得保存在类中的二进制编码进行比较。这样可以在外部定时修
改函数的二进制编码,从而调整权限对应的权限执行码,这样当泄漏权限执行码时可以避免
长期的损失。而且避免了第一种改进方法中“当一个函数标志对应多个权限等级”时的麻烦
。
注:关于gloabRight.getRight()
gloabRight为模块内部的一个类,定义如下:
先定义一个结构体,用于放置函数标志和相应的执行码。
type RRright = record
functionID:String;
functionCord:Tstream;
//由于执行码可能很长,因此Delphi中用流来存储,
//具体编程语言自己决定类型
end;
type TgloabRight = class
private
Right: array of Rright;//动态数组,用于存放函数标志和相应执行码数组大
//小由函数表的记录数决定。
function getRight(const functionID:String:TStream//按函数标志取得相应
//的执行码
public
constructor Create;//构造函数,从数据库中读取信息并初始化Right数组。
destructor Destroy;//析构函数,用于释放Right数组。
end;
用流来存取函数执行码是否可行?在数据库中怎么存储?
感谢您的耐心阅读!
代码仅供描述,有的地方不规范,见谅。
欢迎提供成功的权限管理的案例!
案,请各位高手点评一下优缺点,顺便提供几个权限管理的成功方法。谢谢。
建立一个权限表,包括权限等级,函数标志。用户在登录时用自己的用户名和密码登录之后
,在用户表里记录自己的权限等级,以后每次调用函数都检查用户的权限等级和这个函数的
关系。例:
用户表
用户名 密码 权限等级
Liu 123 1
Zhang 234 2
权限和相应函数对照表
权限等级 函数标志
1 Aaa
2 bbb
1 bbb
用户每次调用函数提供自己的用户名(session)函数可能如下:
procedure Aaa(const session, pwd, out isSuccess)
var
procedureID:String;
begin
isSuccess := false;
procedureID := ‘Aaa’;//函数标志,不是函数名,也可以和函数重名。
Select * from权限和相应函数对照表,用户表 where用户名=session and
密码 = pwd and 用户表.权限等级=权限和相应函数对照表. 权限等级
and函数标志=procedureID;
If 记录数=0 then
exit;//如果此用户名所拥有的权限不拥有此函数的使用权
//则退出。
……//否则执行函数。
……
isSuccess := true;
end;
修改权限等级可执行的函数时,只需在表中插入或删除记录即可
为了不让用户了解更多的组件内部函数,可以自己编写一个程序来进行权限表的修改。
优点:权限管理清晰方便。可以在代码级设定权限。
缺点:每个函数调用都要查询数据库,不知是否服务器受得了。
一个改进方法:
组件模块建立一个全局数组,存放每一个函数调用者的权限等级,在初始化时从数据库中提
取并赋值。用户提交自己的权限等级,然后在函数中判断
用户每次调用函数提供自己的权限等级(level)函数可能如下:
procedure Aaa(const level, out isSuccess)
begin
isSuccess := false;
if level <> gloabRight.getRight(Aaa)
//gloabRight.getRight()为一个类成员方法,用于返回函数标志为Aaa的权限等级。
Exit
else
……//执行函数
……
isSuccess := true;
end;
end;
优点:只在模块初始化时读一次数据库,减少了系统额外负担。
缺点:当一个函数标志对应多个权限等级时,需要编码做额外处理,暂时没仔细想怎么做。
无法对用户提供的level做判断,只能假定是合法的,和直接提供session而不提供密码是
一样的。
另一种改进方法:
权限表
权限等级 权限执行码(暂定)
1 111
2 110
3 100
其中权限执行码根据函数表和权限和相应函数对照表生成
函数表
函数名 二进制编码
Aaa 001
Bbb 010
Ccc 100
权限和相应函数对照表
权限等级 函数标志
1 Aaa
1 Bbb
1 Ccc
2 Bbb
2 Ccc
3 Ccc
用户登录后,从数据库中找出他所拥有权限的执行码发给用户,每次用户调用的时候传递一
个执行码,在函数中进行判断
用户每次调用函数提供自己的权限执行码(exeCode)函数可能如下:
procedure Aaa(const exeCode, out isSuccess)
begin
isSuccess := false;
if (exeCode 逻辑与 001) = 0 then
exit
else
……//执行函数
……
isSuccess := true;
end;
优点:用户提供的是一组看上去无意义的二进制数,提高的攻击的难度。
缺点:函数中权限执行码是写死的,而且随着函数的增多,权限执行码会很长。
两种改进方法的结合:
组件模块初始化时从数据库中动态调出每一个函数的二进制编码,然后在函数中用
gloabRight.getRight()来取得保存在类中的二进制编码进行比较。这样可以在外部定时修
改函数的二进制编码,从而调整权限对应的权限执行码,这样当泄漏权限执行码时可以避免
长期的损失。而且避免了第一种改进方法中“当一个函数标志对应多个权限等级”时的麻烦
。
注:关于gloabRight.getRight()
gloabRight为模块内部的一个类,定义如下:
先定义一个结构体,用于放置函数标志和相应的执行码。
type RRright = record
functionID:String;
functionCord:Tstream;
//由于执行码可能很长,因此Delphi中用流来存储,
//具体编程语言自己决定类型
end;
type TgloabRight = class
private
Right: array of Rright;//动态数组,用于存放函数标志和相应执行码数组大
//小由函数表的记录数决定。
function getRight(const functionID:String:TStream//按函数标志取得相应
//的执行码
public
constructor Create;//构造函数,从数据库中读取信息并初始化Right数组。
destructor Destroy;//析构函数,用于释放Right数组。
end;
用流来存取函数执行码是否可行?在数据库中怎么存储?
感谢您的耐心阅读!
代码仅供描述,有的地方不规范,见谅。
欢迎提供成功的权限管理的案例!