在管理信息系统开发过程中,对于用户权限的控制是一个难点。
1)简单情况下我们设计成多个用户可以多个权限,即用户与权限直接存在多对多关系
a、User对象与Privilege对象定义为:
public class User{
private Long id;
private String name;
private Set<Privilege> privilegeSet=new Set<Privilege>();
}
public class Privilege{
private Long id;
private String name;
private String uri;
private Set<User> userSet=new Set<User>();
}
b、即表关系:
user:id name
privilege:id name uri(路径)
user_privilege:uid pid(形成联合主键)
c、Hibernate中的映射:
User.hbm.xml:
<class name="User" table="tb_user">
<key name="id" type="Long">
<generator class="native"/>
</key>
<property name="name" type="string" length="30"/>
<set name="privilegeSet" table="user_privilege" lazy="false">
<id key="uid"/>
<many-to-many class="Privilege" colunm="pid" />
</set>
</class>
Privilege.hbm.xml:
<class name="Privilege" table="tb_privilege" >
<key name="id">
<generator class="native"/>
</key>
<property name="name" tyep="string" length="30"/>
<property name="name" tyep="string" />
<set name="userSet" table="user_privilege" lazy="false">
<key column="pid">
<many-to-many class="User" column="uid"/>
</set>
</class>
d、启用懒加载,在查询用户信息的时候就查询出它对应的权限列表,即在用户登录时候用户对象就带有权限信息,此时可以一次判断用户拥有哪些信息。
2)在大型信息系统中,很多拥有权限相同的用户,我们可以定义一个角色来管理分配权限。
即一个角色拥有多个权限,一个权限可以属于多个角色。同时一个用户可以拥有多个角色,一个角色可以属于多个用户。
用户和角色之间存在多对多关系,角色和权限之间存在多对多关系
a、User、Privilege、Role类定义为:
public class User{
private Long id;
private String name;
private Set<Role> roleSet=new Set<Role>();
}
public class Privilege{
private Long id;
private String name;
private String uri;
private Set<Role> userSet=new Set<Role>();
}
public class Role{
private Long id;
private String name;
private Set<Privilege> privilegeSet=new Set<Privilege>();
private Set<User> userSet=new Set<User>();
}
b、即表关系:
user:id name
role:id name privilegeSet userSet
privilege:id name uri(路径)
role_privilege:rid pid(形成联合主键)
user_role:uid rid(形成联合主键)
c、Hibernate映射同1)相似
3)权限控制的办法:
1、配置一个服务器启动监听器实现ServletContextListener接口,在服务器启动时候执行contextInitialized()方法中,将要控制的权限的URL放到Application与对象中。
2、通过自定义Struts标签重写AnchorTag类的doEndTag()方法即控制超链接的标签<a>,方法中判断用户是否有权限访问Application中的URI.如果可以显示,否则不显
示。
3、通过定义拦截器,继承AbstractInterceptor类,重写intercept(Actioninvocation invocation)方法,在方法中对登录的用户权限做判断,如果有权限则放行资源return invocation.invoke();否则就跳到没有访问权限的配置页面privilegeError页面
<!-- 声明拦截器和拦截器栈 -->
<interceptors>
<!-- 声明检查权限的拦截器 -->
<interceptor name="PrivilegeInterceptor"
class="cn.caiz.oa.interceptor.PrivilegeInterceptor" />
<!-- 声明拦截器栈包含struts2默认的拦截器-->
<interceptor-stack name="myInterceptor">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="PrivilegeInterceptor" />
</interceptor-stack>
</interceptors>
// 通过url判断用户是否拥有该权限
public boolean hasPrivilegeByUrl(String url) {
boolean flag = false;
// 判断是否是超级管理员
if (isSuper()) {
flag = true;
} else {
// 检查是否有权限(服务器启动的时候已经所有权限的url列表放在application域对象中)
List<String> privilegeUrls = (List<String>) ActionContext
.getContext().getApplication().get("privilegeUrls");
// 如果该访问的url不需要控制则放行资源(即所有的权限列表中并没有)
if (!privilegeUrls.contains(url)) {
flag = true;
// 如果该访问的url需要控制则检查用户是否拥有该权限
} else {
//遍历所有的角色
for (Role role : roles) {
//遍历角色中的权限
for (Privilege privilege : role.getPrivileges()) {
if (url.equals(privilege.getUrl())) {
flag = true;
break;
}
}
}
}
}
return flag;
}
1)简单情况下我们设计成多个用户可以多个权限,即用户与权限直接存在多对多关系
a、User对象与Privilege对象定义为:
public class User{
private Long id;
private String name;
private Set<Privilege> privilegeSet=new Set<Privilege>();
}
public class Privilege{
private Long id;
private String name;
private String uri;
private Set<User> userSet=new Set<User>();
}
b、即表关系:
user:id name
privilege:id name uri(路径)
user_privilege:uid pid(形成联合主键)
c、Hibernate中的映射:
User.hbm.xml:
<class name="User" table="tb_user">
<key name="id" type="Long">
<generator class="native"/>
</key>
<property name="name" type="string" length="30"/>
<set name="privilegeSet" table="user_privilege" lazy="false">
<id key="uid"/>
<many-to-many class="Privilege" colunm="pid" />
</set>
</class>
Privilege.hbm.xml:
<class name="Privilege" table="tb_privilege" >
<key name="id">
<generator class="native"/>
</key>
<property name="name" tyep="string" length="30"/>
<property name="name" tyep="string" />
<set name="userSet" table="user_privilege" lazy="false">
<key column="pid">
<many-to-many class="User" column="uid"/>
</set>
</class>
d、启用懒加载,在查询用户信息的时候就查询出它对应的权限列表,即在用户登录时候用户对象就带有权限信息,此时可以一次判断用户拥有哪些信息。
2)在大型信息系统中,很多拥有权限相同的用户,我们可以定义一个角色来管理分配权限。
即一个角色拥有多个权限,一个权限可以属于多个角色。同时一个用户可以拥有多个角色,一个角色可以属于多个用户。
用户和角色之间存在多对多关系,角色和权限之间存在多对多关系
a、User、Privilege、Role类定义为:
public class User{
private Long id;
private String name;
private Set<Role> roleSet=new Set<Role>();
}
public class Privilege{
private Long id;
private String name;
private String uri;
private Set<Role> userSet=new Set<Role>();
}
public class Role{
private Long id;
private String name;
private Set<Privilege> privilegeSet=new Set<Privilege>();
private Set<User> userSet=new Set<User>();
}
b、即表关系:
user:id name
role:id name privilegeSet userSet
privilege:id name uri(路径)
role_privilege:rid pid(形成联合主键)
user_role:uid rid(形成联合主键)
c、Hibernate映射同1)相似
3)权限控制的办法:
1、配置一个服务器启动监听器实现ServletContextListener接口,在服务器启动时候执行contextInitialized()方法中,将要控制的权限的URL放到Application与对象中。
2、通过自定义Struts标签重写AnchorTag类的doEndTag()方法即控制超链接的标签<a>,方法中判断用户是否有权限访问Application中的URI.如果可以显示,否则不显
示。
3、通过定义拦截器,继承AbstractInterceptor类,重写intercept(Actioninvocation invocation)方法,在方法中对登录的用户权限做判断,如果有权限则放行资源return invocation.invoke();否则就跳到没有访问权限的配置页面privilegeError页面
<!-- 声明拦截器和拦截器栈 -->
<interceptors>
<!-- 声明检查权限的拦截器 -->
<interceptor name="PrivilegeInterceptor"
class="cn.caiz.oa.interceptor.PrivilegeInterceptor" />
<!-- 声明拦截器栈包含struts2默认的拦截器-->
<interceptor-stack name="myInterceptor">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="PrivilegeInterceptor" />
</interceptor-stack>
</interceptors>
// 通过url判断用户是否拥有该权限
public boolean hasPrivilegeByUrl(String url) {
boolean flag = false;
// 判断是否是超级管理员
if (isSuper()) {
flag = true;
} else {
// 检查是否有权限(服务器启动的时候已经所有权限的url列表放在application域对象中)
List<String> privilegeUrls = (List<String>) ActionContext
.getContext().getApplication().get("privilegeUrls");
// 如果该访问的url不需要控制则放行资源(即所有的权限列表中并没有)
if (!privilegeUrls.contains(url)) {
flag = true;
// 如果该访问的url需要控制则检查用户是否拥有该权限
} else {
//遍历所有的角色
for (Role role : roles) {
//遍历角色中的权限
for (Privilege privilege : role.getPrivileges()) {
if (url.equals(privilege.getUrl())) {
flag = true;
break;
}
}
}
}
}
return flag;
}