- 浏览: 2159145 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1878)
- [网站分类]ASP.NET (141)
- [网站分类]C# (80)
- [随笔分类]NET知识库 (80)
- [随笔分类]摘抄文字[非技术] (3)
- [随笔分类]养生保健 (4)
- [网站分类]读书区 (16)
- [随笔分类]赚钱 (7)
- [网站分类].NET新手区 (233)
- [随笔分类]网站 (75)
- [网站分类]企业信息化其他 (4)
- [网站分类]首页候选区 (34)
- [网站分类]转载区 (12)
- [网站分类]SQL Server (16)
- [网站分类]程序人生 (7)
- [网站分类]WinForm (2)
- [随笔分类]错误集 (12)
- [网站分类]JavaScript (3)
- [随笔分类]小说九鼎记 (69)
- [随笔分类]技术文章 (15)
- [网站分类]求职面试 (3)
- [网站分类]其他技术区 (6)
- [网站分类]非技术区 (10)
- [发布至博客园首页] (5)
- [网站分类]jQuery (6)
- [网站分类].NET精华区 (6)
- [网站分类]Html/Css (10)
- [随笔分类]加速及SEO (10)
- [网站分类]Google开发 (4)
- [随笔分类]旅游备注 (2)
- [网站分类]架构设计 (3)
- [网站分类]Linux (23)
- [随笔分类]重要注册 (3)
- [随笔分类]Linux+PHP (10)
- [网站分类]PHP (11)
- [网站分类]VS2010 (2)
- [网站分类]CLR (1)
- [网站分类]C++ (1)
- [网站分类]ASP.NET MVC (2)
- [网站分类]项目与团队管理 (1)
- [随笔分类]个人总结 (1)
- [随笔分类]问题集 (3)
- [网站分类]代码与软件发布 (1)
- [网站分类]Android开发 (1)
- [网站分类]MySQL (1)
- [网站分类]开源研究 (6)
- ddd (0)
- 好久没写blog了 (0)
- sqlserver (2)
最新评论
-
JamesLiuX:
博主,能组个队么,我是Freelancer新手。
Freelancer.com(原GAF – GetAFreelancer)帐户里的钱如何取出? -
yw10260609:
我认为在混淆前,最好把相关代码备份一下比较好,不然项目完成后, ...
DotFuscator 小记 -
日月葬花魂:
大哥 能 加我个QQ 交流一下嘛 ?51264722 我Q ...
web应用程序和Web网站区别 -
iaimg:
我想问下嵌入delphi写的程序总是出现窗体后面感觉有个主窗体 ...
C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部 -
iaimg:
代码地址下不了啊!
C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
权限管理的设计方法是非常重要的,在项目开发中,也是最最基本的。
首先,设置三种要素:用户、群组、角色。
用户为登录用,对应到人。群组对应为用户的集合,是一种特殊的用户。角色为一组权限项的集合,用户(群组)都有各自的角色。
权限的实现通过Permission类和Rule类来实现。
Permission供外部调用,Rule为一个接口,为权限判断规则。
Permission是一个抽象类,有以下方法
public boolean hasPermission(User user,HashMap oldData,Input input);
public String getPermissionName();
public abstract Rule[] getDenyRule();
public abstract Rule[] getAcceptRule();
hasPermission方法供外部调用,已实现,实现方法为先根据getDenyRule()得到的规则判断权限是否被阻拦,再根据getAcceptRule来判断是否有权限。
而Rule接口的接品则由用户自行定义,随包附带了一个已实现的Rule,实现的功能如下:
先寻找User的所有角色,然后判断角色是否有权限,如果无权限则寻找其父级群组,再取父级群组的所有角色进行判断是否有权限,如果无权限则再往上级群组找,直到找最上一级还是无权限才判断为无权限。
现实现判断权限有无权限的方式已可以达成的有以下三种:
1、 是否有操作的权限。
2、 是否有操作的子操作的权限。
3、 在数据为某条件时有操作(子操作)的权限。
在进行程序开发时,第一步,编写User,Group,Role的实现类,已提供了一套XML的实现类。
第二步,写配置文件,进行权限项的配置。
第三步,在程序中要进行权限判断的地方调用Permission.hasPermission方法即可。
以后我会把代码逐天贴出来。
如果大家有什么别的种类权限要进行判断的,请给我发送邮件,我继续改善,欢迎大家多提意见。
==================================================
权限组件之一(用户)
----------------------
首先,我定义了一个用户接口,可以从其中取出其的各种属性.代码如后面所示.用户除了各种不同的属性以外还必须设置其角色以及所属的群组.
然后定义一个AbstractUser把User共性的东西进行处理.所有的取属性的方法都已实现.用户只要根据实现情况继承AbstractUser把自己要定义的属性进行处理即可.(因为每个系统的用户都会有不同的属性,所以留成抽象类供使用者自己扩展). 只要初始化变量description, name ,group ,id, prop,role,propMap即可.
最后定义了一个类UserImpl来实现具体的User作随包的一个User供一般使用者使用.不建议直接使用UserImpl,因为以后的版本可能会重写该类.如果要使用的话可以把该类改名为自己的类即可.
这部分涉及到了一个ResourceLib类,该类中存是我自己定义的存储各种资源配置用的类,可以直接使用.
<script language="JavaScript" src="http://www.im5173.com/ads/ads728x15.js" type="text/javascript"></script>======================User.java===============================
package org.fswan.permission;
import org.fswan.Identity;
import java.util.Properties;
import org.fswan.workflow.exception.CantFoundIDException;
public interface User
{
/**
* 获取用户名
* @return 用户名
*/
public String getName();
/**
* 获取用户描述
* @return 描述
*/
public String getDescription();
/**
* 获取用户标识
* @return 用户标识
*/
public Identity getId();
/**
* 获取属性
* @return 属性值
*/
public Properties getProperties();
/**
* 获取所属组
* @return 组列表
*/
public Group[] getGroups() throws CantFoundIDException;
/**
* 获取所有角色
* @return 角色数组
*/
public Role[] getRoles() throws CantFoundIDException;
/**
* 获取用户用作权限判断的属性
* @param prop 权限属性
* @return 属性值
*/
public Object getPermissionProp(String prop);
}
=======================AbstractUser===================================
package org.fswan.permission;
import java.util.HashMap;
import java.util.Properties;
import org.fswan.Identity;
import org.fswan.workflow.exception.IdentityMappingError;
/**
*
* 实现AbstractUser的类构造必须做的一些事
* 初始化变量description,name,group,id,prop,role,propMap
*/
public class AbstractUser implements User
{
/**
* 描述
*/
protected String description;
/**
* 名称
*/
protected String name;
/**
* 所属的组的标识
*/
protected Identity[] group;
/**
* 用户标识
*/
protected Identity id;
/**
* 属性
*/
protected Properties prop;
/**
* 角色
*/
protected Identity[] role;
/**
* 权限属性存储的位置
*/
protected HashMap propMap;
/* (non-Javadoc)
* @see org.fswan.permission.User#getDescription()
*/
public String getDescription()
{
return description;
}
/* (non-Javadoc)
* @see org.fswan.permission.User#getGroups()
*/
public Group[] getGroups()
{
Group[] groups = new Group[group.length];
for (int i = 0; i < groups.length; i++)
{
try
{
groups[i] = (Group) group[i].newInstance();
} catch (IdentityMappingError e)
{
e.printStackTrace();
}
}
return groups;
}
/* (non-Javadoc)
* @see org.fswan.permission.User#getId()
*/
public Identity getId()
{
return id;
}
/* (non-Javadoc)
* @see org.fswan.permission.User#getName()
*/
public String getName()
{
return name;
}
/* (non-Javadoc)
* @see org.fswan.permission.User#getProperties()
*/
public Properties getProperties()
{
return prop;
}
/* (non-Javadoc)
* @see org.fswan.permission.User#getRoles()
*/
public Role[] getRoles()
{
Role[] roles = new Role[role.length];
for (int i = 0; i < roles.length; i++)
{
try
{
roles[i] = (Role) role[i].newInstance();
} catch (IdentityMappingError e)
{
e.printStackTrace();
}
}
return roles;
}
public String toString()
{
String retStr = id.getIdName();
retStr += ":" + name;
retStr += " " + description + "\n";
retStr += "Group:";
Group[] groups = this.getGroups();
if (groups != null)
{
for (int i = 0; i < groups.length; i++)
{
if (groups[i] != null)
retStr += groups[i].getId().getIdName() + "\t";
}
}
Properties p = getProperties();
Object[] obj = p.keySet().toArray();
for (int i = 0; i < obj.length; i++)
{
retStr+=obj[i]+":"+p.getProperty(obj[i].toString())+"\n";
}
return retStr;
}
/* (non-Javadoc)
* @see org.fswan.permission.User#getPermissionProp(java.lang.String)
*/
public Object getPermissionProp(String prop)
{
return propMap.get(prop);
}
}
==============================UserImpl.java===========================
package org.fswan.permission;
import java.util.ArrayList;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilderFactory;
import org.fswan.Identity;
import org.fswan.IdentityImpl;
import org.fswan.ImplementIdentity;
import org.fswan.ResourceLib;
import org.fswan.workflow.exception.IdentityMappingError;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XMLUser extends AbstractUser implements ImplementIdentity
{
/**
* XML中定义用户的标签
*/
public static final String USER = "User";
public Object newInstance(Identity id)
{
ArrayList sources = ResourceLib.getXmlResource();
for (int i = 0; i < sources.size(); i++)
{
try
{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(sources.get(i).toString());
NodeList nl = doc.getElementsByTagName(USER);
for (int j = 0; j < nl.getLength(); j++)
{
Element tempEl = (Element) nl.item(j);
String idStr = tempEl.getAttribute("id");
if (idStr != null && !idStr.equals(""))
{
if (idStr.equals(id.getIdName()))
{
this.id = new IdentityImpl(Identity.SWITCH, Identity.XMLUSER, idStr);
NodeList tempNl = tempEl.getElementsByTagName("Name");
name = tempNl.item(0).getChildNodes().item(0).getNodeValue();
tempNl = tempEl.getElementsByTagName("Description");
description = tempNl.item(0).getChildNodes().item(0).getNodeValue();
tempNl = tempEl.getElementsByTagName("ParentGroup");
Identity[] groups = new Identity[tempNl.getLength()];
for (int iGroup = 0; iGroup < groups.length; iGroup++)
{
Element tempEl2 = (Element) tempNl.item(iGroup);
String subType = tempEl.getAttribute("subType");
if(subType==null || subType.equals(""))subType = Identity.XMLGROUP;
groups[iGroup] = new IdentityImpl(Identity.GROUP, subType, tempEl2.getAttribute("id"));
}
this.group = groups;
tempNl = tempEl.getElementsByTagName("Role");
Identity[] roles = new Identity[tempNl.getLength()];
for (int iRole = 0; iRole < tempNl.getLength(); iRole++)
{
Element tempEl2 = (Element) tempNl.item(iRole);
String subType = tempEl.getAttribute("subType");
if(subType==null || subType.equals(""))subType = Identity.XMLROLE;
roles[iRole] = new IdentityImpl(Identity.ROLE, subType, tempEl2.getAttribute("id"));
}
this.role = roles;
this.prop = new Properties();
tempNl = tempEl.getElementsByTagName("Property");
if (tempNl != null)
for (int k = 0; k < tempNl.getLength(); k++)
{
Element tempElement = (Element) tempNl.item(k);
System.out.println(tempElement.getAttribute("name"));
this.prop.setProperty(tempElement.getAttribute("name"), tempElement.getAttribute("value"));
}
return this;
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
}
return null;
}
public static void main(String[] args)
{
try
{
ResourceLib.addResource("D:\\eclipse\\workspace\\workflow\\workflow.xml");
User u = (User) new IdentityImpl(Identity.USER, Identity.XMLUSER, "U01").newInstance();
System.out.println(u);
} catch (IdentityMappingError e)
{
e.printStackTrace();
}
}
}
========================XML格式=====================
<User id="U01">
<Name>Swan</Name>
<Description>方志文</Description>
<ParentGroup id="G01"/>
<Property name="SEX" value="male"/>
<Property name="AGE" value="20"/>
</User>
========================XML描述文件==================
<xs:complexType name="User">
<xs:annotation>
<xs:documentation>用户名</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="Name"/>
<xs:element name="Description"/>
<xs:element name="ParentGroup" type="Identity" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="Role" type="Identity" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="Property" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" use="required"/>
<xs:attribute name="value" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" use="required"/>
</xs:complexType>
=========================================================
==========================================================
==========================================================
权限组件之二(群组)
-------------------------
首先,我定义了一个群组接口,除了继承用户的方法以外还有两个方法,getUsers,getSubGroup.代码如后面所示.用户除了各种不同的属性以外还必须设置其角色以及所属的群组.
然后定义一个AbstractGroup,他继承了Group以及AbstractUser,并实现了Group接口定义的两个方法.用户只要根据实现情况继承AbstractGroup把自己要定义的属性进行处理即可.(因为每个系统的用户都会有不同的属性,所以留成抽象类供使用者自己扩展). 只要初始化变量description, name ,group ,id, prop,role,propMap,subGroup,user即可.
最后定义了一个类XMLGroup来实现具体的Group作随包的一个Group供一般使用者使用.不建议直接使用XMLGroup,因为以后的版本可能会重写该类.如果要使用的话可以把该类改名为自己的类即可.
这部分涉及到了一个ResourceLib类,该类中存是我自己定义的存储各种资源配置用的类,可以直接使用.
======================Group.java===============================
package org.fswan.permission;
public interface Group extends User
{
/**
* 获取组下所有的用户
* @return 用户数组
*/
public User[] getUsers();
/**
* 获取组下属的组
* @return 组的数组
*/
public Group[] getSubGroup();
}
=======================AbstractGroup===================================
package org.fswan.permission;
import org.fswan.Identity;
import org.fswan.workflow.exception.IdentityMappingError;
public class AbstractGroup extends AbstractUser implements Group
{
protected Identity[] subGroup;
protected Identity[] user;
/* (non-Javadoc)
* @see org.fswan.permission.Group#getSubGroup()
*/
public Group[] getSubGroup()
{
Group[] groups = new Group[subGroup.length];
for (int i = 0; i < groups.length; i++)
{
try
{
groups[i] = (Group)subGroup[i].newInstance();
} catch (IdentityMappingError e)
{
e.printStackTrace();
}
}
return groups;
}
/* (non-Javadoc)
* @see org.fswan.permission.Group#getUsers()
*/
public User[] getUsers()
{
User[] users = new User[user.length];
for (int i = 0; i < users.length; i++)
{
try
{
users[i] = (User)user[i].newInstance();
} catch (IdentityMappingError e)
{
e.printStackTrace();
}
}
return users;
}
public String toString()
{
String retStr = id.getIdName();
retStr +=":"+name;
retStr += " "+description;
return retStr;
}
}
==============================XMLGroup.java===========================
package org.fswan.permission;
import java.util.ArrayList;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilderFactory;
import org.fswan.Identity;
import org.fswan.IdentityImpl;
import org.fswan.ImplementIdentity;
import org.fswan.ResourceLib;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XMLGroup extends AbstractGroup implements ImplementIdentity
{
/**
* XML中定义群组的标签
*/
public static final String GROUP = "Group";
public Object newInstance(Identity id)
{
ArrayList sources = ResourceLib.getXmlResource();
for (int i = 0; i < sources.size(); i++)
{
try
{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(sources.get(i).toString());
NodeList nl = doc.getElementsByTagName(GROUP);
for (int j = 0; j < nl.getLength(); j++)
{
Element tempEl = (Element)nl.item(j);
String idStr = tempEl.getAttribute("id");
if(idStr!=null && !idStr.equals(""))
{
if(idStr.equals(id.getIdName()))
{
this.id = new IdentityImpl(Identity.SWITCH,Identity.XMLGROUP,idStr);
//加载名称
NodeList tempNl = tempEl.getElementsByTagName("Name");
name = tempNl.item(0).getChildNodes().item(0).getNodeValue();
//加载描述
tempNl = tempEl.getElementsByTagName("Description");
description = tempNl.item(0).getChildNodes().item(0).getNodeValue();
//加载父群组
tempNl = tempEl.getElementsByTagName("ParentGroup");
Identity[] groups = new Identity[tempNl.getLength()];
for (int iGroup=0; iGroup < tempNl.getLength(); iGroup++)
{
tempEl = (Element)tempNl.item(iGroup);
groups[iGroup] = new IdentityImpl(Identity.GROUP,Identity.XMLGROUP,tempEl.getAttribute("id"));
}
this.subGroup = groups;
//加载角色
tempNl = tempEl.getElementsByTagName("Role");
Identity[] roles = new Identity[tempNl.getLength()];
for (int iRole=0; iRole < tempNl.getLength(); iRole++)
{
tempEl = (Element)tempNl.item(iRole);
roles[iRole] = new IdentityImpl(Identity.ROLE,Identity.XMLROLE,tempEl.getAttribute("id"));
}
this.role = roles;
//加载属性
this.prop = new Properties();
tempNl = tempEl.getElementsByTagName("Property");
if(tempNl!=null)
for (int k = 0; k < tempNl.getLength(); k++)
{
Element tempElement = (Element)tempNl.item(k);
this.prop.setProperty(tempElement.getAttribute("name"),tempElement.getAttribute("value"));
}
//加载子群组
tempNl = tempEl.getElementsByTagName("SubGroup");
if (tempNl != null)
{
subGroup = new Identity[tempNl.getLength()];
for (int k = 0; k < subGroup.length; k++)
{
Element tempElement = (Element) tempNl.item(k);
subGroup[k] = new IdentityImpl(Identity.GROUP,Identity.XMLGROUP,tempElement.getAttribute("id"));
}
}
//加载用户
tempNl = tempEl.getElementsByTagName("User");
if (tempNl != null)
{
user = new Identity[tempNl.getLength()];
for (int k = 0; k < subGroup.length; k++)
{
Element tempElement = (Element) tempNl.item(k);
user[k] = new IdentityImpl(Identity.USER,Identity.XMLUSER,tempElement.getAttribute("id"));
}
}
return this;
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
}
return null;
}
}
========================XML格式=====================
<Group id="G01">
<Name>系统部</Name>
<Description>系统部</Description>
</Group>
========================XML描述文件==================
<xs:complexType name="Group">
<xs:annotation>
<xs:documentation>群组</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="User">
<xs:sequence>
<xs:element name="SubGroup" type="Identity" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="User" type="Identity" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
================================================
====================================================
======================================================
权限组件之三(角色)
---------------------------------
首先,我定义了一个角色接口,可以从其中取出其的各种属性.代码如后面所示.
然后定义一个AbstractRole把Role共性的东西进行处理.所有的取属性的方法都已实现.用户只要根据实现情况继承AbstractRole把自己要定义的属性进行处理即可.(因为每个系统的用户都会有不同的属性,所以留成抽象类供使用者自己扩展). 只要初始化变量description, name ,id, prop,users(可能是群组), permissionMap即可.
最后定义了一个类XMLRole来实现具体的Role作随包的一个Role供一般使用者使用.不建议直接使用XMLRole,因为以后的版本可能会重写该类.如果要使用的话可以把该类改名为自己的类即可.
这部分涉及到了一个ResourceLib类,该类中存是我自己定义的存储各种资源配置用的类,可以直接使用.
======================Role.java===============================
package org.fswan.permission;
import org.fswan.Identity;
import java.util.Properties;
import org.fswan.workflow.exception.CantFoundIDException;
public interface Role
{
/**
* 获取角色ID
* @return
*/
public Identity getId();
/**
* 获取角色的名称
* @return 名称
*/
public String getName();
/**
* 获取角色的描述
* @return 描述
*/
public String getDescription();
/**
* 获取角色的所有的用户(组)
* @return 用户
*/
public User[] getUsers() throws CantFoundIDException;
/**
* 角色的属性
* @return 属性值
*/
public Properties getProperties();
/**
* 获取用户用作权限判断的属性
* @param prop 权限属性
* @return 属性值
*/
public Object getPermissionProp(String prop);
}
=======================AbstractRole===================================
package org.fswan.permission;
import java.util.HashMap;
import java.util.Properties;
import org.fswan.Identity;
import org.fswan.workflow.exception.IdentityMappingError;
public class AbstractRole implements Role
{
/**
* 描述
*/
protected String description ;
/**
* 名称
*/
protected String name;
/**
* 标识
*/
protected Identity id;
/**
* 属性
*/
protected Properties prop;
/**
* 该角色所有用户的标识
*/
protected Identity[] users;
/**
* 权限属性表
*/
protected HashMap permissionMap;
/* (non-Javadoc)
* @see org.fswan.permission.Role#getDescription()
*/
public String getDescription()
{
return description;
}
/* (non-Javadoc)
* @see org.fswan.permission.Role#getId()
*/
public Identity getId()
{
return id;
}
/* (non-Javadoc)
* @see org.fswan.permission.Role#getName()
*/
public String getName()
{
return name;
}
/* (non-Javadoc)
* @see org.fswan.permission.Role#getProperties()
*/
public Properties getProperties()
{
return prop;
}
/* (non-Javadoc)
* @see org.fswan.permission.Role#getUsers()
*/
public User[] getUsers()
{
User[] retUser = new User[users.length];
for (int i = 0; i < retUser.length; i++)
{
try
{
retUser[i] = (User)users[i].newInstance();
} catch (IdentityMappingError e)
{
e.printStackTrace();
}
}
return retUser;
}
public String toString()
{
String retStr = id.getIdName();
retStr +=":"+name;
retStr += " "+description;
return retStr;
}
/* (non-Javadoc)
* @see org.fswan.permission.Role#getPermissionProp(java.lang.String)
*/
public Object getPermissionProp(String prop)
{
return permissionMap.get(prop);
}
}
==============================XMLRole.java===========================
/*
* Created on 2004-4-21
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.fswan.permission;
import java.util.ArrayList;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilderFactory;
import org.fswan.Identity;
import org.fswan.IdentityImpl;
import org.fswan.ImplementIdentity;
import org.fswan.ResourceLib;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XMLRole extends AbstractRole implements ImplementIdentity
{
/**
* XML标签用的字符串
*/
public static final String ROLE = "Role";
public Object newInstance(Identity id)
{
ArrayList sources = ResourceLib.getXmlResource();
for (int i = 0; i < sources.size(); i++)
{
try
{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(sources.get(i).toString());
NodeList nl = doc.getElementsByTagName(ROLE);
for (int j = 0; j < nl.getLength(); j++)
{
Element tempEl = (Element)nl.item(j);
String idStr = tempEl.getAttribute("id");
if(idStr!=null && !idStr.equals(""))
{
if(idStr.equals(id.getIdName()))
{
this.id = new IdentityImpl(Identity.SWITCH,Identity.XMLROLE,idStr);
NodeList tempNl = tempEl.getElementsByTagName("Name");
name = tempNl.item(0).getChildNodes().item(0).getNodeValue();
tempNl = tempEl.getElementsByTagName("Description");
description = tempNl.item(0).getChildNodes().item(0).getNodeValue();
this.prop = new Properties();
tempNl = tempEl.getElementsByTagName("Property");
if(tempNl!=null)
for (int k = 0; k < tempNl.getLength(); k++)
{
Element tempElement = (Element)tempNl.item(k);
this.prop.setProperty(tempElement.getAttribute("name"),tempElement.getAttribute("value"));
}
return this;
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
}
return null;
}
}
========================XML格式=====================
<Role id="R01">
<Name>系统管理员</Name>
<Description>系统管理员</Description>
</Role>
========================XML描述文件==================
<xs:complexType name="Role">
<xs:annotation>
<xs:documentation>角色名</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="Name"/>
<xs:element name="Description"/>
<xs:element name="Property" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" use="required"/>
</xs:complexType>
======================================================================
=======================================================================
=======================================================================
权限组件之四(规则)
---------------------------
定义好User,Group,Role了以后,下面我定义了权限判断的规则.
首先定义Rule接口,见Rule.java.Rule只做一件事判断User是否有权限.
然后我实现了一个Rule,见RuleImpl.java.
这部分涉及到了一个Input类,这个类是一个输入的类,接口如Input.java.这个通过继承该接口可以使用各种方式数据(HTTP,XML,SOAP……)作为输入数据.
Permission为权限类,下面一篇会介绍.
======================Rule.java===============================
package org.fswan.permission;
import java.util.HashMap;
import org.fswan.Input;
/**
* 用来进行判断的规则.
* 供Permission调用
*/
public interface Rule
{
public boolean pass(Permission permission,User user,HashMap oldData,Input input);
}
=======================RuleImpl===================================
package org.fswan.permission;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import org.fswan.Input;
/**
*
*/
public class RuleImpl implements Rule
{
/* (non-Javadoc)
* @see org.fswan.permission.Rule#pass(org.fswan.permission.Permission, org.fswan.permission.User, org.fswan.permission.Role, org.fswan.permission.Group, java.util.HashMap, org.fswan.Input)
*/
public boolean pass(Permission permission, User user, HashMap oldData, Input input)
{
try
{
Role[] roles = user.getRoles();
if (roles != null)
{
for (int i = 0; i < roles.length; i++)
{
if (hasPermission(permission, user, roles[i], oldData, input)) //有权限
return true;
}
}
Group[] groups = user.getGroups();
if (groups != null)
for (int i = 0; i < groups.length; i++)
{
if (pass(permission, groups[i], oldData, input))
return true;
}
return false;
} catch (Exception ex)
{
ex.printStackTrace();
}
return false;
}
/**
* 判断用户的某个角色是否有权限进行某操作
* @param permission 权限
* @param user 用户
* @param role 角色
* @param oldData 数据
* @param input 输入
* @return 是否有权限
*/
private boolean hasPermission(Permission permission, User user, Role role, HashMap oldData, Input input)
{
//如角色没有该权限ID则无权限
if (role.getPermissionProp(permission.getPermissionName()) == null)
return false;
//如果权限还要判断层别
if (permission.getPermissionItem() != null)
{
ArrayList item = permission.getPermissionItem();
boolean accept = true;
ArrayList roleItem = (ArrayList) role.getPermissionProp(permission.getPermissionName());
ttt : for (int i = 0; i < roleItem.size(); i++)
{
Properties p = (Properties) roleItem.get(i);
accept = true;
for (int j = 0; j < item.size(); j++)
{
if (p.getProperty(item.get(j).toString()) != null
&& p.getProperty(item.get(j).toString()).indexOf(oldData.get(item.get(j).toString()).toString())
!= -1) //如果无权限
continue ttt;
}
return true;
}
return false;
}
return true;
}
}
=============================Input.java=======================
package org.fswan;
/**
* @author 方志文
*
* 输入数据的接口,作为主类的数据输入式,
* 现可以从xml,HttpServletRequest和JSPUpload获取数据
*
*/
public interface Input {
/**
* 获取参数的值,如果无该参数则返回null,如果该参数对应多个值则返回其第一个值
* @param parameter 参数
* @return 值
*/
public String getParameter(String parameter);
/**
* 获取参数的值列表
* @param parameter 参数
* @return 值
*/
public String[] getParameterValues(String parameter);
/**
* 获取参数名的列表
* @return 所有的参数的名
*/
public String[] getParameterNames();
/**
* 获取数据源
* @return 数据源
*/
public Object getSource();
/**
* 设置参数,如果已存在该参数,则原来的作废
* @param parameter 参数
* @param value 值
*/
public void setParameter(String parameter,String value);
/**
* 设置参数,如果已存在该参数,则把原来的作废
* @param parameter 参数
* @param values 值
*/
public void setParameter(String parameter,String[] values);
/**
* 添加参数,如果已存在该参数,则把该值添加到原值后成数组
* @param parameter 参数
* @param value 值
*/
public void addParameter(String parameter,String value);
/**
* 添加参数(多个值),如果已存在该参数,则把该值添加到原值后成数组
* @param parameter 参数
* @param values 值
*/
public void addParameter(String parameter,String[] values);
}
============================================================
===============================================================
===============================================================
权限组件五(权限)(完)
----------------------------
最后,我定义了一个Permission类把所有的元素连接起来形成一个完整权限判断组件。代码如下。用户继承该类时要完两个方法getDenyRule,getAcceptRule即可。
当我们进行权限判断时只要调用hasPermission(User user,HashMap oldData,Input input)即可。其后三个参数分别为用户,数据,输入。用户为在判断的人,数据为原有数据,比较进行更新操作时,oldData为老数据,input在前一部分有介绍,为一个通用的输入方式。比WEB输入Post或Get方式等,可以转换成一个Input类,也可以手动新建一个Input.为操作以及其数据的集合。
在Permission类中进行了DenyRule和AcceptRule的判断,只要有一个DenyRule规则符合要求,则认为该用户无权限进行操作,如果用户的没被DenyRule排除则进行AcceptRule的判断,只要有一个规则符合要求则认为该用户有权限。
因为本人比较懒所以Permission的实现还没有写出一个通用的。
综上所述,使用此权限组件要进行以下几项工作:
1、 编写User的实现。
2、 编写Group的实现。
3、 编写Role的实现。
4、 编写Permission的实现。(过段时间我会摆个通用的上来)
5、 编写N个Rule(同你的系统要进行权限判断相对应)。
6、 在程序中调用Permission.hasPermission判断。
======================Permission.java===============================
package org.fswan.permission;
import java.util.ArrayList;
import java.util.HashMap;
import org.fswan.Input;
/**
* 权限判断类
*/
public abstract class Permission
{
public String permission;
public String subPermission;
protected ArrayList prop;
public boolean hasPermission(User user,HashMap oldData,Input input)
{
Rule[] rules = getDenyRule();
boolean accept = true;
for (int i = 0; i < rules.length; i++)
{
if(!rules[i].pass(this,user,oldData,input))
{
accept = false;
break;
}
}
if(accept)return false;
rules = getAcceptRule();
for (int i = 0; i < rules.length; i++)
{
if(!rules[i].pass(this,user,oldData,input))
return false;
}
return true;
}
public String getPermissionName()
{
if(subPermission==null)return permission;
return permission+":"+subPermission;
}
public ArrayList getPermissionItem()
{
return prop;
}
public abstract Rule[] getDenyRule();
public abstract Rule[] getAcceptRule();
}
==================================================
==================================================
==================================================
权限组件所缺的文件
原意是给大家看一下结构,没想大家都那么关心,我现在把所有的代码贴上来,谢谢大家关心.
唉,BLOG好烦啊,无法直接上传文件要一个一个贴
================ResourceLib.java ============
package org.fswan;
import java.util.ArrayList;
import java.util.Properties;
/**
* 用来存储通用的XML配置文件位置和数据库连接属性.
* 作为org.fswan里所有的包中类的基础配置文件.
*/
public class ResourceLib
{
/**
* 驱动的字符串
*/
public static final String DRIVER = "Driver";
/**
* 数据库连接字符串
*/
public static final String URL = "URL";
/**
* 用户
*/
public static final String USER = "User";
/**
* 密码
*/
public static final String PASSWORD = "Password";
/**
* 所有的XML配置文件的存储位置,存储的对象为URL
*/
private static ArrayList resource = new ArrayList();
/**
* 存储所有的数据库配置.
* 所有的数据库存储位置格式为:
* 对象为Properties对象
* 而properties对象里包含:
* {@link #DRIVER DRIVER},{@link #URL URL},{@link #USER USER},{@link #PASSWORD PASSWORD},{@link #VIEW VIEW},{@link #TYPE TYPE}六个属性分别对应
* 数据库的驱动,边接字符串,用户名,密码,视图,类型
* 或者
* {@link #JNDI JNDI},{@link #VIEW VIEW},{@link #TYPE TYPE}
* JNDI名,视图,类型
* 类型是以下的一个
* {@link #WORKFLOW WORKFLOW}
* {@link #BRAND BRAND}
* {@link #STATUS STATUS}
* {@link #SWITCH SWITCHER}
* {@link #WORKUNIT WORKUNIT}
* {@link #USER USER}
*/
private static ArrayList prop = new ArrayList();
/**
* 获取所有的XML资源
* @return XML资源泉
*/
public static ArrayList getXmlResource()
{
return resource;
}
/**
* 获取所有的数据库连接属性
* @return 数据库链接属性
*/
public static ArrayList getConnection()
{
return prop;
}
/**
* 增加XML资源
* @param source XML资源
*/
public static void addResource(String source)
{
synchronized(resource)
{
resource.add(source);
}
}
/**
* 增加数据库链接属性
* @param pro 数据库链接属性
*/
public static void addDataProperty(Properties pro)
{
synchronized(prop)
{
prop.add(pro);
}
}
}
==============Input.java============
/*
* Created on 2003-11-20
*
* Create By 方志文
* email:fswan@yeah.net
*/
package org.fswan;
/**
* @author 方志文
*
* 输入数据的接口,作为主类的数据输入式,
* 现可以从xml,HttpServletRequest和JSPUpload获取数据
*
*/
public interface Input {
/**
* 获取参数的值,如果无该参数则返回null,如果该参数对应多个值则返回其第一个值
* @param parameter 参数
* @return 值
*/
public String getParameter(String parameter);
/**
* 获取参数的值列表
* @param parameter 参数
* @return 值
*/
public String[] getParameterValues(String parameter);
/**
* 获取参数名的列表
* @return 所有的参数的名
*/
public String[] getParameterNames();
/**
* 获取数据源
* @return 数据源
*/
public Object getSource();
/**
* 设置参数,如果已存在该参数,则原来的作废
* @param parameter 参数
* @param value 值
*/
public void setParameter(String parameter,String value);
/**
* 设置参数,如果已存在该参数,则把原来的作废
* @param parameter 参数
* @param values 值
*/
public void setParameter(String parameter,String[] values);
/**
* 添加参数,如果已存在该参数,则把该值添加到原值后成数组
* @param parameter 参数
* @param value 值
*/
public void addParameter(String parameter,String value);
/**
* 添加参数(多个值),如果已存在该参数,则把该值添加到原值后成数组
* @param parameter 参数
* @param values 值
*/
public void addParameter(String parameter,String[] values);
}
================ManualInput.java ==============
package org.fswan;
public class ManualInput extends AbstractInput
{
/* (non-Javadoc)
* @see org.fswan.Input#getSource()
*/
public Object getSource()
{
return null;
}
}
===================Identity.java==========
package org.fswan;
import org.fswan.workflow.exception.IdentityMappingError;
/**
* @author Administrator
* 这个接是一个标识,用来唯一标识所有的工作流,状态,切换开关,分枝操作
*/
public interface Identity
{
/**
* 工作流的标识
*/
public static final int WORKFLOW = 0;
/**
* 分枝操作的标识
*/
public static final int BRAND = 1;
/**
* 状态的标识
*/
public static final int STATUS =2;
/**
* 切换开关的标识
*/
public static final int SWITCH = 3;
/**
* 用户的标识
*/
public static final int USER = 4;
/**
* 工作单元
*/
public static final int WORKUNIT = 5;
/**
* 角色
*/
public static final int ROLE = 6;
/**
* 群组
*/
public static final int GROUP = 7;
public static final int VIEWCLASS = 255;
public static final String XMLWORKFLOW = "XMLWorkFlow";
public static final String XMLBRAND = "XMLBrand";
public static final String XMLSWITCHER = "XMLSwitcher";
public static final String XMLSTATUS = "XMLStatus";
public static final String XMLWORKUNIT = "XMLWorkUnit";
public static final String DBWORKFLOW = "DBWorkFlow";
public static final String DBBRAND = "DBBrand";
public static final String DBSWITCHER = "DBSwitcher";
public static final String DBSTATUS = "DBStatus";
public static final String DBWORKUNIT = "DBWorkUnit";
public static final String XMLUSER = "XMLUser";
public static final String XMLGROUP = "XMLGroup";
public static final String XMLROLE = "XMLRole";
/**
* 获取标识的类型
* 是以下常量中的一个
* {@link #WORKFLOW WORKFLOW}
* {@link #BRAND BRAND}
* {@link #STATUS STATUS}
* {@link #SWITCH SWITCH}
* {@link #USER USER}
* @return 标识的类型
*/
public int getIdType();
/**
* 获取标识的名称
* @return 标识的名称
*/
public String getIdName();
/**
* 返回该Identity的子类型,该子类型是给newInstance使用的
* @return 子类型
*/
public String getSubType();
/**
* 通过ID生成实例
* @return 实例
* @throws IdentityMappingError 找不到生器异常
*/
public Object newInstance() throws IdentityMappingError;
}
=============IdentityImpl.java===============
package org.fswan;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import org.fswan.workflow.exception.IdentityMapHadExist;
import org.fswan.workflow.exception.IdentityMappingError;
/**
* 唯一标识符类.
* 由唯一标识符可以调用相应的类来生成相对应的接口生成相对应的实例
* 不同种类标识符生成相对应的实例的类在{@link map}中进行映射定义.
* 可调用静态方法register进行注册.
*/
public class IdentityImpl implements Identity
{
private String name;
private int type;
private String subType;
/**
* 从ID到类的映射表
*/
private static Hashtable map = new Hashtable();
public IdentityImpl(int type,String subType,String name)
{
this.type = type;
this.subType=subType;
this.name = name;
}
public IdentityImpl genIdentity(int type)
{
SimpleDateFormat f = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String name = f.format(new Date());
return new IdentityImpl(type,"",name);
}
/* (non-Javadoc)
* @see org.fswan.Identity#getIdName()
*/
public String getIdName()
{
return name;
}
/* (non-Javadoc)
* @see org.fswan.Identity#getIdType()
*/
public int getIdType()
{
return type;
}
public String getSubType()
{
return subType;
}
public String toString()
{
return "["+type+":"+name+"]";
}
public boolean equals(Object obj)
{
if(obj instanceof Identity)
{
return this.getIdType()==((Identity)obj).getIdType()
&& getIdName().equals(((Identity)obj).getIdName());
}
return false;
}
/**
* 查找相应对的对象
* @return 实例化后的对象
* @throws IdentityMappingError 映射实现不了,
* 可能是因为注册的类不存在或者无法实例化该类,或该类不是ImplementIdentity
*/
public Object newInstance() throws IdentityMappingError
{
try
{
if(map.get(subType)==null)return null;
ImplementIdentity ids = (ImplementIdentity)Class.forName(map.get(subType).toString()).newInstance();
return ids.newInstance(this);
} catch (InstantiationException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
throw new IdentityMappingError();
}
/**
* 注册标识种类到生成实例类的映射
* @param type 类型
* @param obj 相对应的类名
* @throws IdentityMapHadExist 异常,(该类型已注册)
*/
public static void register(String subType,String obj) throws IdentityMapHadExist
{
if(map.containsKey(subType)) throw new IdentityMapHadExist(subType);
map.put(subType,obj);
}
static
{
try
{
IdentityImpl.register(Identity.DBBRAND,"org.fswan.workflow.DBWrokFlow");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.DBSTATUS,"org.fswan.workflow.DBStatus");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.DBSWITCHER,"org.fswan.workflow.DBSwitcher");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.DBWORKFLOW,"org.fswan.workflow.DBWrokFlow");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.DBWORKUNIT,"org.fswan.workflow.DBWorkUnit");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLBRAND,"org.fswan.workflow.XMLBrand");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLGROUP,"org.fswan.permission.XMLGroup");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLROLE,"org.fswan.permission.XMLRole");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLSTATUS,"org.fswan.workflow.XMLStatus");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLSWITCHER,"org.fswan.workflow.XMLSwitcher");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLUSER,"org.fswan.permission.XMLUser");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLWORKFLOW,"org.fswan.workflow.XMLWorkFlow");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
try
{
IdentityImpl.register(Identity.XMLWORKUNIT,"org.fswan.workflow.XMLWorkUnit");
} catch (IdentityMapHadExist e)
{
e.printStackTrace();
}
}
}
==================ImplementIdentity.java=============
package org.fswan;
/**
* @author swan
* 通过ID实例化相应的对象.
* 当用户自己实现User,Role,Group,Brand等对象时,通过ID来查找相对应的对象,
* 在类IdentityImpl对象中根据注册各种Identity类型对应的InstanceIdentity对象
* 来实例化对象.
* 注意:该接口的子类的构造方法一定是PUBLIC且不带任何参数.
*/
public interface ImplementIdentity
{
/**
* 实例化ID相对对应的对象.
* @param identity 要实例化的对象的ID
* @return 对象
*/
public Object newInstance(Identity identity);
}
===========CantFoundIDException.java-==============
package org.fswan.workflow.exception;
import org.fswan.Identity;
/**
* @author Administrator
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class CantFoundIDException extends Exception
{
public CantFoundIDException(Identity id)
{
super("Can't Found ID:["+id.getIdType()+":"+id.getIdName()+"]");
}
}
==================IdentityMapHadExist.java============
package org.fswan.workflow.exception;
/**
* @author swan
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class IdentityMapHadExist extends Exception
{
public IdentityMapHadExist(String subType)
{
super("Mapping Had Exist:"+subType);
}
}
==================IdentityMappingError.java============
package org.fswan.workflow.exception;
/**
* @author swan
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class IdentityMappingError extends Exception
{
public IdentityMappingError()
{
super("The Mapping Class is not InstanceIdentity.");
}
}
=================TypeCastException.java ============
package org.fswan.workflow.exception;
import org.fswan.db.Field;
/**
* 类型转换异常,当从字符串转成特定类型出错时抛出
*/
public class TypeCastException extends Exception
{
/**
* 构造函数
* @param field 字段
* @param str 字符串值
*/
public TypeCastException(Field field,String str)
{
super(str+" cast to "+field + " Error");
}
}
思路很好!!!!!!!!!
author: EdwarddotNet
前言:
权限往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断“Who对What(Which)进行How的操作”的逻辑表达式是否为真。针对不同的应用,需要根据项目的实际情况和具体架构,在维护性、灵活性、完整性等N多个方案之间比较权衡,选择符合的方案。
目标:
直观,因为系统最终会由最终用户来维护,权限分配的直观和容易理解,显得比较重要,系统不辞劳苦的实现了组的继承,除了功能的必须,更主要的就是因为它足够直观。
简单,包括概念数量上的简单和意义上的简单还有功能上的简单。想用一个权限系统解决所有的权限问题是不现实的。设计中将常常变化的“定制”特点比较强的部分判断为业务逻辑,而将常常相同的“通用”特点比较强的部分判断为权限逻辑就是基于这样的思路。
扩展,采用可继承在扩展上的困难。的Group概念在支持权限以组方式定义的同时有效避免了重定义时
现状:
对于在企业环境中的访问控制方法,一般有三种:
1.自主型访问控制方法。目前在我国的大多数的信息系统中的访问控制模块中基本是借助于自主型访问控制方法中的访问控制列表(ACLs)。
2.强制型访问控制方法。用于多层次安全级别的军事应用。
3.基于角色的访问控制方法(RBAC)。是目前公认的解决大型企业的统一资源访问控制的有效方法。其显著的两大特征是:1.减小授权管理的复杂性,降低管理开销。2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。
名词:
粗粒度:表示类别级,即仅考虑对象的类别(the type of object),不考虑对象的某个特
定实例。比如,用户管理中,创建、删除,对所有的用户都一视同仁,并不区分操作的具体对象实例。
细粒度:表示实例级,即需要考虑具体对象的实例(the instance of object),当然,细
粒度是在考虑粗粒度的对象类别之后才再考虑特定实例。比如,合同管理中,列表、删除,需要区分该合同实例是否为当前用户所创建。
原则:
权限逻辑配合业务逻辑。即权限系统以为业务逻辑提供服务为目标。相当多细粒度的权限问题因其极其独特而不具通用意义,它们也能被理解为是“业务逻辑”的一部分。比如,要求:“合同资源只能被它的创建者删除,与创建者同组的用户可以修改,所有的用户能够浏览”。这既可以认为是一个细粒度的权限问题,也可以认为是一个业务逻辑问题。在这里它是业务逻辑问题,在整个权限系统的架构设计之中不予过多考虑。当然,权限系统的架构也必须要能支持这样的控制判断。或者说,系统提供足够多但不是完全的控制能力。即,设计原则归结为:“系统只提供粗粒度的权限,细粒度的权限被认为是业务逻辑的职责”。
需要再次强调的是,这里表述的权限系统仅是一个“不完全”的权限系统,即,它不提供所有关于权限的问题的解决方法。它提供一个基础,并解决那些具有“共性”的(或者说粗粒度的)部分。在这个基础之上,根据“业务逻辑”的独特权限需求,编码实现剩余部分(或者说细粒度的)部分,才算完整。回到权限的问题公式,通用的设计仅解决了Who+What+How 的问题,其他的权限问题留给业务逻辑解决。
概念:
Who:权限的拥用者或主体(Principal、User、Group、Role、Actor等等)
What:权限针对的对象或资源(Resource、Class)。
How:具体的权限(Privilege, 正向授权与负向授权)。
Role:是角色,拥有一定数量的权限。
Operator:操作。表明对What的How 操作。
说明:
User:与 Role 相关,用户仅仅是纯粹的用户,权限是被分离出去了的。User是不能与 Privilege 直接相关的,User 要拥有对某种资源的权限,必须通过Role去关联。解决 Who 的问题。
Resource:就是系统的资源,比如部门新闻,文档等各种可以被提供给用户访问的对象。资源可以反向包含自身,即树状结构,每一个资源节点可以与若干指定权限类别相关可定义是否将其权限应用于子节点。
Privilege:是Resource Related的权限。就是指,这个权限是绑定在特定的资源实例上的。比如说部门新闻的发布权限,叫做"部门新闻发布权限"。这就表明,该Privilege是一个发布权限,而且是针对部门新闻这种资源的一种发布权限。Privilege是由Creator在做开发时就确定的。权限,包括系统定义权限和用户自定义权限用户自定义权限之间可以指定排斥和包含关系(如:读取,修改,管理三个权限,管理 权限 包含 前两种权限)。Privilege 如"删除" 是一个抽象的名词,当它不与任何具体的 Object 或 Resource 绑定在一起时是没有任何意义的。拿新闻发布来说,发布是一种权限,但是只说发布它是毫无意义的。因为不知道发布可以操作的对象是什么。只有当发布与新闻结合在一起时,才会产生真正的 Privilege。这就是 Privilege Instance。权限系统根据需求的不同可以延伸生很多不同的版本。
Role:是粗粒度和细粒度(业务逻辑)的接口,一个基于粗粒度控制的权限框架软件,对外的接口应该是Role,具体业务实现可以直接继承或拓展丰富Role的内容,Role不是如同User或Group的具体实体,它是接口概念,抽象的通称。
Group:用户组,权限分配的单位与载体。权限不考虑分配给特定的用户。组可以包括组(以实现权限的继承)。组可以包含用户,组内用户继承组的权限。Group要实现继承。即在创建时必须要指定该Group的Parent是什么Group。在粗粒度控制上,可以认为,只要某用户直接或者间接的属于某个Group那么它就具备这个Group的所有操作许可。细粒度控制上,在业务逻辑的判断中,User仅应关注其直接属于的Group,用来判断是否“同组” 。Group是可继承的,对于一个分级的权限实现,某个Group通过“继承”就已经直接获得了其父Group所拥有的所有“权限集合”,对这个Group而言,需要与权限建立直接关联的,仅是它比起其父Group需要“扩展”的那部分权限。子组继承父组的所有权限,规则来得更简单,同时意味着管理更容易。为了更进一步实现权限的继承,最直接的就是在Group上引入“父子关系”。
User与Group是多对多的关系。即一个User可以属于多个Group之中,一个Group可以包括多个User。子Group与父Group是多对一的关系。Operator某种意义上类似于Resource + Privilege概念,但这里的Resource仅包括Resource Type不表示Resource Instance。Group 可以直接映射组织结构,Role 可以直接映射组织结构中的业务角色,比较直观,而且也足够灵活。Role对系统的贡献实质上就是提供了一个比较粗颗粒的分配单位。
Group与Operator是多对多的关系。各概念的关系图示如下:
解释:
Operator的定义包括了Resource Type和Method概念。即,What和How的概念。之所以将What和How绑定在一起作为一个Operator概念而不是分开建模再建立关联,这是因为很多的How对于某What才有意义。比如,发布操作对新闻对象才有意义,对用户对象则没有意义。
How本身的意义也有所不同,具体来说,对于每一个What可以定义N种操作。比如,对于合同这类对象,可以定义创建操作、提交操作、检查冲突操作等。可以认为,How概念对应于每一个商业方法。其中,与具体用户身份相关的操作既可以定义在操作的业务逻辑之中,也可以定义在操作级别。比如,创建者的浏览视图与普通用户的浏览视图要求内容不同。既可以在外部定义两个操作方法,也可以在一个操作方法的内部根据具体逻辑进行处理。具体应用哪一种方式应依据实际情况进行处理。
这样的架构,应能在易于理解和管理的情况下,满足绝大部分粗粒度权限控制的功能需要。但是除了粗粒度权限,系统中必然还会包括无数对具体Instance的细粒度权限。这些问题,被留给业务逻辑来解决,这样的考虑基于以下两点:
一方面,细粒度的权限判断必须要在资源上建模权限分配的支持信息才可能得以实现。比如,如果要求创建者和普通用户看到不同的信息内容,那么,资源本身应该有其创建者的信息。另一方面,细粒度的权限常常具有相当大的业务逻辑相关性。对不同的业务逻辑,常常意味着完全不同的权限判定原则和策略。相比之下,粗粒度的权限更具通用性,将其实现为一个架构,更有重用价值;而将细粒度的权限判断实现为一个架构级别的东西就显得繁琐,而且不是那么的有必要,用定制的代码来实现就更简洁,更灵活。
所以细粒度控制应该在底层解决,Resource在实例化的时候,必需指定Owner和GroupPrivilege在对Resource进行操作时也必然会确定约束类型:究竟是OwnerOK还是GroupOK还是AllOK。Group应和Role严格分离User和Group是多对多的关系,Group只用于对
发表评论
-
UML
2010-08-09 11:39 1303开放分类:计算机技术计算机术语计算机科学 收藏分享到顶[6] ... -
用WebService实现调用新浪的天气预报功能
2010-07-15 21:47 2973用WebService实现调用新 ... -
Cookie简介及JSP处理Cookie的方法
2010-07-29 09:28 970Cookie简介及JSP处理Cookie的方法 一.什么是 ... -
SQL Server 2005/2008 用户数据库文件默认路径和默认备份路径修改方法
2010-06-09 22:16 1256一直想把数据库的默认 ... -
C#Winform调用网页中的JS方法
2010-07-12 11:07 2230其实还是还是相当的简单,本文将详细的用代码来展示一下如何调用, ... -
用WebService实现调用新浪的天气预报功能
2010-07-15 21:47 1508用WebService实现调用新 ... -
SQL Server 2005/2008 用户数据库文件默认路径和默认备份路径修改方法
2010-06-09 22:16 1086一直想把数据库的默认 ... -
基于 VS 2010 阐述C# 4个特性
2010-05-28 09:26 1078基于 VS 2010 阐述C# 4个特性基于 VS 20 ... -
Google AdSense中文官方博客今天公布了AdSense内容广告与AdSense搜索广告的收入分成比例
2010-05-25 09:12 1123google adsense 的广告分成比例总算是公布出来了。 ... -
权限管理数据表设计说明
2010-05-21 15:19 1082权限管理数据表设计说明 B/S系统中的权限比C/S中的更显的 ... -
多表分页存储过程
2010-05-17 14:25 1059分页存储过程 在网站设计,网页开发中,是要被经常遇到的。 ... -
vs2010跟vs2008比较增加了哪些功能
2010-05-18 09:10 2254随着vs2010的发布,新的 ... -
COM域名难逃实名监管 CN域名简化流程抢用户
2010-05-13 09:22 1189互联网实名制的落实第 ... -
网站安全之XSS漏洞攻击以及防范措施
2010-04-29 08:59 1426在网站开发中,安全问题是重中之重的问题,特别像一个sql注入, ... -
深入了解ASP.NET运行内幕
2010-04-28 09:04 1170做事情要知道根本所在 ... -
WebBrowser中显示乱码
2010-04-22 09:09 1738最近在开发cs项目的时候,因为嵌套了一个网页,要用到we ... -
vps配置笔记(10)架设svn服务
2010-04-21 09:41 1266linux 下面架设svn服务器,有点难度,我找了好多资料,现 ... -
IEnumerable
2010-04-16 09:12 1271在平常的代码编写中,虽然不常用到Ienumerable 但却不 ... -
JS代码实例:实现随机加载不同的CSS样式
2010-04-19 13:38 1419如果让网页浏览者每次打开页面都有新的感觉,可以通过替换css样 ... -
FCKeidtor的toolbarset的设置
2010-04-20 09:18 1415在软件开过过程中,经过要用到编辑器,其中FCKeidtor应该 ...
相关推荐
权限管理设计方法 权限管理设计方法 权限管理设计方法 权限管理设计方法 权限管理设计方法
首先,权限管理设计方法通常包括三个基本要素:用户(User)、群组(Group)和角色(Role)。用户代表实际的登录人,群组是一系列用户的集合,它允许将相似权限的用户分组,而角色是一组权限项的集合。用户和群组都...
权限管理设计方案详细设计 权限管理设计方案是为了设计一套具有较强可扩展性的用户认证管理系统,需要建立用户、角色和权限等数据库表,并且建立之间的关系。本设计方案的主要内容包括用户认证管理设计、角色设计、...
【权限管理系统设计方案】是关于如何构建一个有效管理用户权限的系统的详细文档。权限设计的核心在于理解用户、组、角色和权限这四个基本...这种设计方法适用于大型企业或组织,以实现对复杂用户权限的有效管理和控制。
通用权限管理设计是构建复杂应用系统的关键组成部分,其目的是实现灵活、通用且易于管理的权限控制,以适应不同用户和场景的需求。权限管理涉及到多个核心概念,包括权限、用户、角色和组,它们之间有着复杂的关系。...
"java系统权限管理设计" java系统权限管理设计是指在java系统中实现业务系统中的用户权限管理。权限管理是指对系统操作的权限控制,确保只有经过授权的用户可以访问系统的相关功能。 在设计java系统权限管理时,...
权限管理设计涉及如何控制用户访问特定资源、执行操作或获取信息。以下是对几种常见的网站权限管理设计的详细阐述: 1. **角色基础访问控制 (Role-Based Access Control, RBAC)** RBAC 是一种广泛采用的权限管理...
根据提供的标题、描述以及部分难以辨识的内容,我们可以推断出这篇文章主要关注的是“权限管理设计”的一些心得和技巧。由于部分内容无法明确解读,这里将重点围绕“权限管理设计”进行深入探讨,分享一些在实际工作...
"通用权限管理系统设计篇"着重探讨了如何设计一个适用于多种场景、能够处理不同用户和角色权限的系统。在这个主题下,我们将深入理解权限管理的核心概念、设计原则以及实现策略。 一、权限管理基础 权限管理主要...
总结来说,基于RBAC的权限管理数据库表设计涵盖了角色、权限、用户、角色-权限关联、用户-角色关联等多个核心组件,通过这些组件的组合,可以构建出一个强大且易于维护的权限管理体系。在实际应用中,还可以根据业务...
本文将深入探讨“角色权限管理设计方案”,基于提供的描述和标签,我们将详细阐述这一主题,以便理解如何有效地设计和实现一个权限控制系统。 首先,我们要明白权限管理的核心目标是确保用户只能访问他们被授权的...
首先,标题“通用权限管理系统的设计与实现”直接指向了文章的主要内容,即设计并实现一个通用的权限管理系统。在IT行业中,权限管理系统(PMS)是确保应用程序安全的重要组成部分,它负责管理用户对系统资源的访问...
### 基于角色的权限管理数据库设计 #### 概述 本文档主要介绍了一种基于角色的权限管理系统(RBAC)的数据库设计方案,并通过具体的SQL脚本实现了该方案的基本功能。RBAC(Role-Based Access Control)是一种常用的...
下面将详细讨论权限管理模块的设计要点和实现方法。 首先,权限管理模块的基础是用户和角色的概念。用户是系统中的实际操作者,而角色则是一组预定义的权限集合。通过分配角色给用户,可以批量设置用户的访问权限。...
在本文中,我们将深入探讨用户权限管理的设计与实现,基于提供的文件名"实现业务系统中的用户权限管理--设计篇.docx"和"实现业务系统中的用户权限管理--实现篇.docx"来解析这一主题。 首先,我们要理解用户权限管理...
在设计B/S业务系统中的权限管理系统时,首要目标是确保只有经过授权的用户才能访问特定的功能,防止非法用户的侵入。权限管理对于B/S系统至关重要,因为与C/S系统相比,浏览器作为通用客户端无法像定制客户端那样...
详细的权限管理系统设计 权限管理系统是每个 B/S 系统中不可或缺的一部分,它可以控制用户对系统的访问权限,确保系统的安全性和可靠性。本文将详细介绍如何设计一个详细的权限管理系统,满足大部分 B/S 系统对用户...
### OA权限管理设计的实现 #### 一、引言 在现代企业信息系统中,权限管理是确保信息安全与高效协作的关键环节。本文将详细介绍一个面向管理信息系统(MIS)的权限管理设计方案,该方案旨在提高系统的安全性与灵活性...
### OA系统权限管理设计方案 #### 一、引言 随着企业规模的不断扩大和技术的发展,办公自动化(OA)系统已经成为提高工作效率、规范管理流程的重要工具。权限管理作为OA系统中的核心功能之一,对于确保数据安全、...
在IT行业中,权限管理和数据库设计是构建安全、高效软件系统的核心组成部分。权限管理涉及到用户角色、操作权限、访问控制等方面,而数据库设计则关乎数据的存储、查询效率以及系统的扩展性。下面将深入探讨这两个...