关于web应用程序安全的思考(序)
2008-11-26 13:36:02 来源:WEB开发网另外权限数据库设计,权限管理方式(分配和移除权限),群组策略,管理员策略等都是可以随系统大小来进行自定义的,当然最好给出一个比较稳定的方案,这样就不用每次都去考虑这个问题。
以下为笔者常用权限架构方案:
群组表:
Groups(GroupID,GroupDesc,AppID)
(AppID为系统ID,因为笔者的所用系统基本上共享一套权限管控方案。如果权限只是For单个系统建表,AppID可以省略,以下不再解释)
群组成员表:
GroupMembers (GroupID,UserID)
用户权限表:
UserRights(UserID,ObjectID,ObjectType,AppID)
ObjectType表示ObjectID是什么数据,如Fact表示是厂别ID,Function表示是功能ID。这样一次就可以满足多种权限的设定了
群组权限表
GroupRights(GroupID,ObjectID,ObjectType,AppID)
管理员表
UserAdmin(UserID,ObjectType,AppID)
某个权限类别的管理员,如有这样一笔数据 UserID:1,ObjectType:Fact。表明UserID为1的用户拥有所有厂别权限
有了这些架构,就可以轻松实现IRightProvider:
/// <summary>
/// 默认权限实做(简单的判断权限)
/// </summary>
class DefaultRightProvider : IRightProvider
{
IDataProvider _dataProvider; //权限数据提供者
public DefaultRightProvider(IDataProvider dataProvider)
{
_dataProvider = dataProvider;
}
#region IRightProvider 成员
public bool HasRight(string userID, string objectID)
{
List<string> data = GetRights(userID);
if (data != null && data.Contains(objectID))
return true;
return false;
}
public List<string> GetRights(string userID)
{
if (_dataProvider != null)
{
return new List<string>(_dataProvider.GetData(userID));
}
return null;
}
#endregion
}
/// <summary>
/// 权限数据的读取策略
/// </summary>
interface IDataProvider
{
/// <summary>
/// 获取某个用户的权限数据
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
IList<string> GetData(string userID);
}
/// <summary>
/// 使用管理员,群组策略的权限机制
/// </summary>
class GroupAdminDataProvider : IDataProvider
{
string _appID;
string _objectType;
/// <summary>
/// 某一系统,某一权限类别的权限数据访问接口
/// </summary>
/// <param name="appID"></param>
/// <param name="objectType"></param>
public GroupAdminDataProvider(string appID, string objectType)
{
_appID = appID;
_objectType = objectType;
}
List<string> getGroupData(string groupID)
{
//调用数据访问层(或其它接口层),获取group的权限对象
}
List<string> getUserData(string userID)
{
//调用数据访问层(或其它接口层),获取user的权限对象
}
List<string> getAllData()
{
//调用数据访问层(或其它接口层),获取当前类别的所有对象
}
List<string> getUserGroup(string userID)
{
//调用数据访问层(或其它接口层),获取user所在的所有群组ID
}
public bool IsAdmin(string userID)
{
//调用数据访问层(或其它接口层),判断管理员权限
}
void addNoReplica(List<string> desList, List<string> addList)
{
if (addList != null && addList.Count > 0)
{
foreach (string addItem in addList)
{
if (!desList.Contains(addItem))
desList.Add(addItem);
}
}
}
public IList<string> GetData(string userID)
{
if (IsAdmin(userID))
return getAllData();
else
{
List<string> ret = new List<string>();
//加入本身权限
List<string> userDatas = getUserData(userID);
addNoReplica(ret, userDatas);
//加入群组权限
List<string> groups = getUserGroup(userID);
if (groups != null)
{
foreach (string groupID in groups)
{
List<string> groupDatas = getGroupData(groupID);
addNoReplica(ret, groupDatas);
}
}
return ret;
}
}
}
更多精彩
赞助商链接