如上图所示是我们设计的E-R图,如图
1:一个角色可以有多个不同的权限,一个权限也可以对应多个角色
2:一个角色可以对应多个用户,一个用户可以是多种角色
3: 一个权限可以对应多个子权限,形成权限树
权限管理模块就是通过用户,组,权限型成的板块
如上图所示是设计出来的类图
具体的类
/**
* 权限实体
* @author zhaoqx
*
*/
public class Privilege {
private Long id;
private String name;//权限的名称
private String url;//权限对应的请求URL
private Privilege parent;//上级权限
private Set<Privilege> children = new HashSet<Privilege>();//下级权限
private Set<Role> roles = new HashSet<Role>();//当前权限对应的角色集合
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Privilege getParent() {
return parent;
}
public void setParent(Privilege parent) {
this.parent = parent;
}
public Set<Privilege> getChildren() {
return children;
}
public void setChildren(Set<Privilege> children) {
this.children = children;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
/**
* 角色实体
*/
public class Role {
private Long id;
private String name;
private String description;
private Set<User> users = new HashSet<User>();
private Set<Privilege> privileges = new HashSet<Privilege>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void setPrivileges(Set<Privilege> privileges) {
this.privileges = privileges;
}
public Set<Privilege> getPrivileges() {
return privileges;
}
}
/**
* 用户实体
* @author zhaoqx
*
*/
public class User {
private Long id;
private String loginName;
private String name;
private int gender;
private String phone;
private String email;
private String description;
private String password;
private Department department;
private Set<Role> roles = new HashSet<Role>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
hibernate映射文件配置privilege
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.oa.domain.Privilege" table="itcast_privilege">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<property name="url"/>
<!-- 下级权限和上级权限的多对一关系 -->
<many-to-one name="parent" class="cn.itcast.oa.domain.Privilege" column="parentId"/>
<!-- 上级权限和下级权限的一对多关系 -->
<set name="children" order-by="id">
<key column="parentId"/>
<one-to-many class="cn.itcast.oa.domain.Privilege"/>
</set>
<!-- 权限和角色的多对多关系 -->
<set name="roles" table="itcast_role_privilege">
<key column="privilegeId"/>
<many-to-many class="cn.itcast.oa.domain.Role" column="roleId"/>
</set>
</class>
</hibernate-mapping>
角色的映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.oa.domain.Role" table="itcast_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<property name="description" length="128"/>
<!-- 岗位和用户的多对多关系 -->
<set name="users" table="itcast_user_role">
<key column="roleId"/>
<many-to-many class="cn.itcast.oa.domain.User" column="userId"/>
</set>
<!-- 角色和权限的多对多关系 -->
<set name="privileges" table="itcast_role_privilege">
<key column="roleId"/>
<many-to-many class="cn.itcast.oa.domain.Privilege" column="privilegeId"/>
</set>
</class>
</hibernate-mapping>
//用户的映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.oa.domain.User" table="itcast_user">
<id name="id">
<generator class="native"/>
</id>
<property name="loginName" length="32"/>
<property name="name"></property>
<property name="password"></property>
<property name="phone"></property>
<property name="email"></property>
<property name="gender"></property>
<property name="description"></property>
<!-- 用户和部门的多对一关系 -->
<many-to-one name="department" class="cn.itcast.oa.domain.Department" column="departmentId"/>
<!-- 用户和岗位的多对多关系 -->
<set name="roles" table="itcast_user_role">
<key column="userId"/>
<many-to-many class="cn.itcast.oa.domain.Role" column="roleId"/>
</set>
</class>
</hibernate-mapping>
1:在spring中配置监听器,在项目加载的时候监听执行获取到用户的所有权限
<!-- 必须放在spring的监听器后面 -->
<listener>
<listener-class>cn.itcast.oa.listener.OAInitListener</listener-class>
</listener>
2:监听器类:在初始化ServletContext的时候自动加载权限数据到application作用域中
/**
* 项目启动时加载权限数据的监听器
* @author zhaoqx
*
*/
public class OAInitListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent arg0) {
}
/**
* 初始化方法
*/
public void contextInitialized(ServletContextEvent sce) {
// 1 获取spring容器
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
// 2从spring容器中获取privilegeService
IPrivilegeService service = (IPrivilegeService) applicationContext.getBean("privilegeServiceImpl");
// 3使用service查询权限数据
List<Privilege> topList = service.findTopList();
// 4将权限数据放入application作用域
sce.getServletContext().setAttribute("privilegeTopList", topList);
System.out.println("权限数据已经放入application作用域了");
//查询所有要进行校验的权限URL
List<String> allUrl = service.findAllUrl();
sce.getServletContext().setAttribute("allUrl", allUrl);
}
}
3 定义默认的拦截器
<!-- 声明自定义拦截器 -->
<interceptors>
<interceptor name="checkPrivilegeInterceptor" class="cn.itcast.oa.interceptor.CheckPrivilegeInterceptor"></interceptor>
<!-- 自定义拦截器栈 -->
<interceptor-stack name="myInterceptor">
<interceptor-ref name="checkPrivilegeInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 指定默认拦截器栈 -->
<default-interceptor-ref name="myInterceptor"></default-interceptor-ref>
1.用户没登陆
(1)用户访问Login.action直接放行
(2)访问其他的xxxx.action返回登陆页面
2 .用户已经登陆
(1)查询所有需要做权限校验的Url
(2)判断用户访问的url需不需要做权限校验
(3)如果需要做权限校验,那么判断当前用户对用的角色,是否有访问当前URL的权限,如果有放行,如果没有就提示越权
(4)如果不用做越权判断,比如一些页面动态加载的action那么就直接放行
/**
* 进行权限检查的拦截器
* @author zhaoqx
*
*/
public class CheckPrivilegeInterceptor extends AbstractInterceptor{
/**
* 拦截方法
*/
public String intercept(ActionInvocation ai) throws Exception {
//从Session中获取登录用户
User user = (User) ServletActionContext.getRequest().getSession().getAttribute("loginUser");
String actionName = ai.getProxy().getActionName();
String namespace = ai.getProxy().getNamespace();
String url = namespace + actionName;// /user_addUI
if(url.endsWith("UI")){
//如果访问URL以UI结尾,就去除
url = url.substring(0, url.length() - 2);
}
//System.out.println("访问URL=" + url);
// 一 ,用户没有登录
if(user == null){
// a 如果用户访问的是登录功能,则放行
if("/user_login".equals(url)){
return ai.invoke();
}else{
// b 如果用户访问的不是登录功能,则跳转到登录页面
return "loginUI";
}
}else{
// 二, 用户已经登录
List<String> allUrl = (List<String>) ServletActionContext.getServletContext().getAttribute("allUrl");
//如果用户访问的是要验证的权限
if(allUrl.contains(url)){
boolean b = user.hasPrivilegeByUrl(url);
if(b){
// a 如果用户有权限,则放行
return ai.invoke();
}else{
// b 如果用户没有权限,则跳转到没有权限的提示页面
return "noPrivilegeUI";
}
}else{
//如果用户访问的不是要验证的权限
return ai.invoke();
}
}
}
}