入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

JavaWeb 案例——访问权限控制

创建时间:2016-04-22 投稿人: 浏览次数:15258


一、功能介绍

       每个网站都涉及到访问权限的控制。每个站点资源都需要被管理起来,用户只有具有访问某个资源的特定权限,才能够访问,否则拒绝访问。

二、项目分析

       我们要实现网站的访问权限控制,就应该从 URI 入手,站点的每个资源都用唯一的 URI 描述,我们为想要管理起来的 URI 增加上权限属性,当用户访问资源时我们要先检查用户是否具有权限。这个项目我采用过滤器技术实现权限拦截,下一个项目我将采用注解+动态代理实现权限的拦截。

        我们需要编写一个过滤器,拦截用户的每个访问请求。再依据 URI 判断是否需要权限。这个是比较简单的,关键就是我们如何将这种权限关系描述出来,如果使用过滤器技术,我们就不得不使用数据库来将每个权限、资源等保存起来。一个资源需要一个权限,一个权限对应多个角色,一个角色可以拥有多个权限,一个用户拥有多个角色,一个角色又可以被多个用户引用。所以资源与权限是一对一关系,权限与角色是多对多关系,角色与用户也是多对多关系。因此在数据库我们需要6张表来保存关系。

 


  1. 一、对象关系  资源、权限、角色、用户  
  2.   
  3.     资源      ------>      权限      一对多  
  4.     权限      <----->       角色      多对多  
  5.     角色      <----->       用户      多对多  
  6.       
  7.     资源:  
  8.         String id   编号  
  9.         String uri  资源uri  
  10.         String description  描述  
  11.         Permission permission   该资源需要的权限  
  12.           
  13.     权限:  
  14.         String id   编号  
  15.         String name 权限名  
  16.         String description 权限描述  
  17.           
  18.     角色:  
  19.         String id   编号  
  20.         String name 角色名  
  21.         String description 角色描述  
  22.         Set<Permission> set 该角色具有的权限  
  23.           
  24.     用户:  
  25.         String id   编号  
  26.         String username 用户名  
  27.         String password 密码  
  28.         Set<Role> set 该用户都具有的角色  
  29.           
  30. 二、数据库实现  
  31.   
  32. create database if not exists sys_permission;  
  33. use sys_permission;  
  34.   
  35. create table if not exists resource(  
  36.     id varchar(40) primary key,  
  37.     uri varchar(255) unique,  
  38.     description varchar(255),  
  39.     permission_id varchar(40),  
  40.     constraint rPermission_id_FK foreign key(permission_id) references permission(id)  
  41. );  
  42.   
  43. create table if not exists permission(  
  44.     id varchar(40) primary key,  
  45.     name varchar(40) unique,  
  46.     description varchar(255)  
  47. );  
  48.   
  49. create table if not exists role(  
  50.     id varchar(40) primary key,  
  51.     name varchar(40) unique,  
  52.     description varchar(255)  
  53. );  
  54.   
  55. create table if not exists user(  
  56.     id varchar(40) primary key,  
  57.     username varchar(40) not null unique,  
  58.     password varchar(40) not null  
  59. );  
  60.   
  61. create table if not exists permission_role(  
  62.     permission_id varchar(40) not null,  
  63.     role_id varchar(40) not null,  
  64.     constraint permission_id_FK foreign key(permission_id) references permission(id),  
  65.     constraint role_id_FK foreign key(role_id) references role(id),  
  66.     constraint primary key(permission_id,role_id)  
  67. );  
  68.   
  69. create table if not exists user_role(  
  70.     user_id varchar(40) not null,  
  71.     role_id varchar(40) not null,  
  72.     constraint user_id_FK foreign key(user_id) references user(id),  
  73.     constraint uRole_id_FK foreign key(role_id) references role(id),  
  74.     constraint primary key(user_id,role_id)  
  75. );  


三、项目新技术

       1、采用 sitemesh 框架为每个页面动态增加模版。原理:sitemesh 实际上也是一个过滤器,当用户访问一个页面时,sitemesh 将请求拦截下来,在服务器以后使用 response 写出数据的时候,实际上是写到了代理对象的缓存中,当数据读写完,sitemesh 再对数据进行包装之后再打给浏览器。

         2、采用 windows 命令初始化数据库。我们将数据库的初始化信息写在文件中,当在浏览器访问初始化 Servlet 时,将使用 windows 命令将文件中的数据导入到 MySQL 



  1. package cn.dk.domain;  
  2.   
  3. public class Permission {  
  4.   
  5.     private String id;  
  6.     private String name;  
  7.     private String description;  
  8.   
  9.     public String getId() {  
  10.         return id;  
  11.     }  
  12.   
  13.     public void setId(String id) {  
  14.         this.id = id;  
  15.     }  
  16.   
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.   
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.   
  25.     public String getDescription() {  
  26.         return description;  
  27.     }  
  28.   
  29.     public void setDescription(String description) {  
  30.         this.description = description;  
  31.     }  
  32.   
  33.     @Override  
  34.     public int hashCode() {  
  35.         final int prime = 31;  
  36.         int result = 1;  
  37.         result = prime * result + ((id == null) ? 0 : id.hashCode());  
  38.         return result;  
  39.     }  
  40.   
  41.     @Override  
  42.     public boolean equals(Object obj) {  
  43.         if (this == obj)  
  44.             return true;  
  45.         if (obj == null)  
  46.             return false;  
  47.         if (getClass() != obj.getClass())  
  48.             return false;  
  49.         final Permission other = (Permission) obj;  
  50.         if (id == null) {  
  51.             if (other.id != null)  
  52.                 return false;  
  53.         } else if (!id.equals(other.id))  
  54.             return false;  
  55.         return true;  
  56.     }  
  57.   
  58. }  

[java] view plain copy


 print?

  1. package cn.dk.domain;  
  2.   
  3. public class Resource {  
  4.   
  5.     private String id;  
  6.     private String uri;  
  7.     private String description;  
  8.     private Permission permission;  
  9.   
  10.     public String getId() {  
  11.         return id;  
  12.     }  
  13.   
  14.     public void setId(String id) {  
  15.         this.id = id;  
  16.     }  
  17.   
  18.     public String getUri() {  
  19.         return uri;  
  20.     }  
  21.   
  22.     public void setUri(String uri) {  
  23.         this.uri = uri;  
  24.     }  
  25.   
  26.     public String getDescription() {  
  27.         return description;  
  28.     }  
  29.   
  30.     public void setDescription(String description) {  
  31.         this.description = description;  
  32.     }  
  33.   
  34.     public Permission getPermission() {  
  35.         return permission;  
  36.     }  
  37.   
  38.     public void setPermission(Permission permission) {  
  39.         this.permission = permission;  
  40.     }  
  41. }  

[java] view plain copy


 print?

  1. package cn.dk.domain;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.   
  6. public class Role {  
  7.   
  8.     public Role() {  
  9.         super();  
  10.         this.permissions = new HashSet<Permission>();  
  11.     }  
  12.   
  13.     private String id;  
  14.     private String name;  
  15.     private String description;  
  16.     private Set<Permission> permissions;  
  17.   
  18.     public String getId() {  
  19.         return id;  
  20.     }  
  21.   
  22.     public void setId(String id) {  
  23.         this.id = id;  
  24.     }  
  25.   
  26.     public String getName() {  
  27.         return name;  
  28.     }  
  29.   
  30.     public void setName(String name) {  
  31.         this.name = name;  
  32.     }  
  33.   
  34.     public String getDescription() {  
  35.         return description;  
  36.     }  
  37.   
  38.     public void setDescription(String description) {  
  39.         this.description = description;  
  40.     }  
  41.   
  42.     public Set<Permission> getPermissions() {  
  43.         return permissions;  
  44.     }  
  45.   
  46.     public void setPermissions(Set<Permission> permissions) {  
  47.         this.permissions = permissions;  
  48.     }  
  49. }  

[java] view plain copy


 print?

  1. package cn.dk.domain;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.   
  6. public class User {  
  7.       
  8.     public User(){  
  9.         super();  
  10.         this.roles = new HashSet<Role>();  
  11.     }  
  12.   
  13.     private String id;  
  14.     private String username;  
  15.     private String password;  
  16.     private Set<Role> roles;  
  17.   
  18.     public String getId() {  
  19.         return id;  
  20.     }  
  21.   
  22.     public void setId(String id) {  
  23.         this.id = id;  
  24.     }  
  25.   
  26.     public String getUsername() {  
  27.         return username;  
  28.     }  
  29.   
  30.     public void setUsername(String username) {  
  31.         this.username = username;  
  32.     }  
  33.   
  34.     public String getPassword() {  
  35.         return password;  
  36.     }  
  37.   
  38.     public void setPassword(String password) {  
  39.         this.password = password;  
  40.     }  
  41.   
  42.     public Set<Role> getRoles() {  
  43.         return roles;  
  44.     }  
  45.   
  46.     public void setRoles(Set<Role> roles) {  
  47.         this.roles = roles;  
  48.     }  
  49. }  

[java] view plain copy


 print?

  1. package cn.dk.dao;  
  2.   
  3. import java.util.List;  
  4.   
  5. import cn.dk.domain.Permission;  
  6.   
  7. public interface IPermissionDao {  
  8.   
  9.     // 插入新权限  
  10.     void insertPermission(Permission permission);  
  11.   
  12.     // 删除权限  
  13.     void deletePermission(String id);  
  14.   
  15.     // 根据id查找权限  
  16.     Permission findPermissionById(String id);  
  17.   
  18.     // 查找所有权限  
  19.     @SuppressWarnings("unchecked")  
  20.     List<Permission> findAllPermission();  
  21.   
  22. }  

[java] view plain copy


 print?

  1. package cn.dk.dao;  
  2.   
  3. import java.util.List;  
  4.   
  5. import cn.dk.domain.Resource;  
  6.   
  7. public interface IResourceDao {  
  8.   
  9.     // 增加资源  
  10.     void insertResource(Resource resource);  
  11.   
  12.     // 修改资源  
  13.     void updateResource(Resource resource);  
  14.   
  15.     // 查找所有资源  
  16.     @SuppressWarnings("unchecked")  
  17.     List<Resource> findAllResource();  
  18.   
  19.     // 根据uri查找资源  
  20.     Resource findResourceByURI(String uri);  
  21.   
  22.     // 根据id查找资源  
  23.     Resource findResourceById(String id);  
  24.   
  25.     // 删除资源  
  26.     void deleteResource(String id);  
  27.   
  28. }  

[java] view plain copy


 print?

  1. package cn.dk.dao;  
  2.   
  3. import java.util.List;  
  4. import cn.dk.domain.Role;  
  5.   
  6. public interface IRoleDao {  
  7.   
  8.     // 新增角色  
  9.     void insertRole(Role role);  
  10.   
  11.     // 更新角色  
  12.     void updateRole(Role role);  
  13.   
  14.     // 删除角色  
  15.     void deleteRole(String id);  
  16.   
  17.     // 根据id查找角色  
  18.     @SuppressWarnings("unchecked")  
  19.     Role findRoleById(String id);  
  20.   
  21.     // 查找所有角色  
  22.     @SuppressWarnings("unchecked")  
  23.     List<Role> fineAllRole();  
  24.   
  25. }  

[java] view plain copy


 print?

  1. package cn.dk.dao;  
  2.   
  3. import java.util.List;  
  4. import cn.dk.domain.User;  
  5.   
  6. public interface IUserDao {  
  7.   
  8.     // 插入用户  
  9.     void insertUser(User user);  
  10.   
  11.     // 更新用户  
  12.     void updateUser(User user);  
  13.   
  14.     // 删除用户  
  15.     void deleteUser(String id);  
  16.   
  17.     // 根据id查找用户  
  18.     @SuppressWarnings("unchecked")  
  19.     User findUserById(String id);  
  20.   
  21.     // 查找所有用户  
  22.     @SuppressWarnings("unchecked")  
  23.     List<User> findAllUser();  
  24.       
  25.     User login(String username, String password);  
  26. }  

[java] view plain copy


 print?

  1. package cn.dk.dao.impl;  
  2.   
  3. import java.sql.SQLException;  
  4. import java.util.List;  
  5. import org.apache.commons.dbutils.QueryRunner;  
  6. import org.apache.commons.dbutils.handlers.BeanHandler;  
  7. import org.apache.commons.dbutils.handlers.BeanListHandler;  
  8. import cn.dk.dao.IPermissionDao;  
  9. import cn.dk.domain.Permission;  
  10. import cn.dk.utils.DBUtils;  
  11.   
  12. public class PermissionDaoImpl implements IPermissionDao {  
  13.   
  14.     // 插入新权限  
  15.     public void insertPermission(Permission permission) {  
  16.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  17.         String sql = "insert into permission (id,name,description) values(?,?,?)";  
  18.         Object[] params = { permission.getId(), permission.getName(),  
  19.                 permission.getDescription() };  
  20.         try {  
  21.             runner.update(sql, params);  
  22.         } catch (SQLException e) {  
  23.             throw new RuntimeException(e);  
  24.         }  
  25.     }  
  26.   
  27.     // 删除权限  
  28.     public void deletePermission(String id) {  
  29.         QueryRunner runer = new QueryRunner(DBUtils.getDataSource());  
  30.         String sql = "update resource set permission_id=null where permission_id=?";  
  31.         try {  
  32.             runer.update(sql, id);  
  33.             sql = "delete from permission where id=?";  
  34.             runer.update(sql, id);  
  35.         } catch (SQLException e) {  
  36.             throw new RuntimeException(e);  
  37.         }  
  38.     }  
  39.   
  40.     // 根据id查找权限  
  41.     public Permission findPermissionById(String id) {  
  42.         QueryRunner runer = new QueryRunner(DBUtils.getDataSource());  
  43.         String sql = "select id,name,description from permission where id=?";  
  44.         Object[] params = { id };  
  45.         try {  
  46.             return (Permission) runer.query(sql, new BeanHandler(  
  47.                     Permission.class), params);  
  48.         } catch (SQLException e) {  
  49.             throw new RuntimeException(e);  
  50.         }  
  51.     }  
  52.   
  53.     // 查找所有权限  
  54.     @SuppressWarnings("unchecked")  
  55.     public List<Permission> findAllPermission() {  
  56.         List<Permission> list = null;  
  57.         QueryRunner runer = new QueryRunner(DBUtils.getDataSource());  
  58.         String sql = "select id,name,description from permission";  
  59.         try {  
  60.             list = (List<Permission>) runer.query(sql, new BeanListHandler(  
  61.                     Permission.class));  
  62.         } catch (SQLException e) {  
  63.             throw new RuntimeException(e);  
  64.         }  
  65.         return list;  
  66.     }  
  67. }  

[java] view plain copy


 print?

  1. package cn.dk.dao.impl;  
  2.   
  3. import java.sql.SQLException;  
  4. import java.util.List;  
  5. import org.apache.commons.dbutils.QueryRunner;  
  6. import org.apache.commons.dbutils.handlers.BeanHandler;  
  7. import org.apache.commons.dbutils.handlers.BeanListHandler;  
  8. import cn.dk.dao.IResourceDao;  
  9. import cn.dk.domain.Permission;  
  10. import cn.dk.domain.Resource;  
  11. import cn.dk.utils.DBUtils;  
  12.   
  13. public class ResourceDaoImpl implements IResourceDao {  
  14.   
  15.     // 增加资源  
  16.     public void insertResource(Resource resource) {  
  17.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  18.         String sql = "insert into resource (id,uri,description,permission_id) values(?,?,?,?)";  
  19.         Object[] params = { resource.getId(), resource.getUri(),  
  20.                 resource.getDescription(), resource.getPermission().getId() };  
  21.         try {  
  22.             runner.update(sql, params);  
  23.         } catch (SQLException e) {  
  24.             throw new RuntimeException(e);  
  25.         }  
  26.     }  
  27.   
  28.     // 修改资源  
  29.     public void updateResource(Resource resource) {  
  30.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  31.         String sql = "update resource set uri=?,description=?,permission_id=? where id=?";  
  32.         Object[] params = { resource.getUri(), resource.getDescription(),  
  33.                 resource.getPermission().getId(), resource.getId() };  
  34.         try {  
  35.             runner.update(sql, params);  
  36.         } catch (SQLException e) {  
  37.             throw new RuntimeException(e);  
  38.         }  
  39.     }  
  40.   
  41.     // 查找所有资源  
  42.     @SuppressWarnings("unchecked")  
  43.     public List<Resource> findAllResource() {  
  44.         List<Resource> list = null;  
  45.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  46.         String sql = "select id,uri,description from resource";  
  47.         try {  
  48.             list = (List<Resource>) runner.query(sql, new BeanListHandler(  
  49.                     Resource.class));  
  50.             for (Resource resource : list) {  
  51.                 sql = "select p.id,p.name,p.description from permission p,resource r where r.permission_id=p.id and r.id=?";  
  52.                 Object[] params = { resource.getId() };  
  53.                 Permission permission = (Permission) runner.query(sql,  
  54.                         new BeanHandler(Permission.class), params);  
  55.                 resource.setPermission(permission);  
  56.             }  
  57.         } catch (SQLException e) {  
  58.             throw new RuntimeException(e);  
  59.         }  
  60.         return list;  
  61.     }  
  62.   
  63.     // 根据uri查找资源  
  64.     public Resource findResourceByURI(String uri) {  
  65.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  66.         String sql = "select id,uri,description from resource where uri=?";  
  67.         Object[] params = { uri };  
  68.         try {  
  69.             Resource resource = (Resource) runner.query(sql, new BeanHandler(  
  70.                     Resource.class), params);  
  71.             if (resource == null)  
  72.                 return null;  
  73.             sql = "select p.id,p.name,p.description from permission p,resource r where r.permission_id=p.id and r.id=?";  
  74.             params = new Object[] { resource.getId() };  
  75.             Permission permission = (Permission) runner.query(sql,  
  76.                     new BeanHandler(Permission.class), params);  
  77.             resource.setPermission(permission);  
  78.             return resource;  
  79.         } catch (SQLException e) {  
  80.             throw new RuntimeException(e);  
  81.         }  
  82.     }  
  83.   
  84.     // 根据id查找资源  
  85.     public Resource findResourceById(String id) {  
  86.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  87.         String sql = "select id,uri,description from resource where id=?";  
  88.         Object[] params = { id };  
  89.         try {  
  90.             Resource resource = (Resource) runner.query(sql, new BeanHandler(  
  91.                     Resource.class), params);  
  92.             sql = "select p.id,p.name,p.description from permission p,resource r where r.permission_id=p.id and r.id=?";  
  93.             params = new Object[] { resource.getId() };  
  94.             Permission permission = (Permission) runner.query(sql,  
  95.                     new BeanHandler(Permission.class), params);  
  96.             resource.setPermission(permission);  
  97.             return resource;  
  98.         } catch (SQLException e) {  
  99.             throw new RuntimeException(e);  
  100.         }  
  101.     }  
  102.   
  103.     // 删除资源  
  104.     public void deleteResource(String id) {  
  105.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  106.         String sql = "delete from resource where id=?";  
  107.         Object[] params = { id };  
  108.         try {  
  109.             runner.update(sql, params);  
  110.         } catch (SQLException e) {  
  111.             throw new RuntimeException(e);  
  112.         }  
  113.     }  
  114. }  

[java] view plain copy


 print?

  1. package cn.dk.dao.impl;  
  2.   
  3. import java.sql.SQLException;  
  4. import java.util.HashSet;  
  5. import java.util.List;  
  6. import java.util.Set;  
  7. import org.apache.commons.dbutils.QueryRunner;  
  8. import org.apache.commons.dbutils.handlers.BeanHandler;  
  9. import org.apache.commons.dbutils.handlers.BeanListHandler;  
  10. import cn.dk.dao.IRoleDao;  
  11. import cn.dk.domain.Permission;  
  12. import cn.dk.domain.Role;  
  13. import cn.dk.utils.DBUtils;  
  14.   
  15. public class RoleDaoImpl implements IRoleDao {  
  16.   
  17.     // 新增角色  
  18.     public void insertRole(Role role) {  
  19.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  20.         String sql = "insert into role (id,name,description) values(?,?,?)";  
  21.         Object[] params = { role.getId(), role.getName(), role.getDescription() };  
  22.         try {  
  23.             runner.update(sql, params);  
  24.             sql = "insert into permission_role (permission_id,role_id) values(?,?)";  
  25.             Set<Permission> set = role.getPermissions();  
  26.             for (Permission permission : set) {  
  27.                 params = new Object[] { permission.getId(), role.getId() };  
  28.                 runner.update(sql, params);  
  29.             }  
  30.         } catch (SQLException e) {  
  31.             throw new RuntimeException(e);  
  32.         }  
  33.     }  
  34.   
  35.     // 更新角色  
  36.     public void updateRole(Role role) {  
  37.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  38.         Set<Permission> set = role.getPermissions();  
  39.         String sql = "delete from permission_role where role_id=?";  
  40.         try {  
  41.             runner.update(sql, role.getId());  
  42.             sql = "update role set name=?,description=? where id=?";  
  43.             Object[] params = { role.getName(), role.getDescription(),  
  44.                     role.getId() };  
  45.             runner.update(sql, params);  
  46.             sql = "insert into permission_role (permission_id,role_id) values(?,?)";  
  47.             for (Permission permission : set) {  
  48.                 params = new Object[] { permission.getId(), role.getId() };  
  49.                 runner.update(sql, params);  
  50.             }  
  51.         } catch (SQLException e) {  
  52.             throw new RuntimeException(e);  
  53.         }  
  54.     }  
  55.   
  56.     // 删除角色  
  57.     public void deleteRole(String id) {  
  58.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  59.         String sql = "delete from permission_role where role_id=?";  
  60.         try {  
  61.             runner.update(sql, id);  
  62.             sql = "delete from role where id=?";  
  63.             runner.update(sql, id);  
  64.         } catch (SQLException e) {  
  65.             throw new RuntimeException(e);  
  66.         }  
  67.     }  
  68.   
  69.     // 根据id查找角色  
  70.     @SuppressWarnings("unchecked")  
  71.     public Role findRoleById(String id) {  
  72.         QueryRunner runner = new QueryRunner(DBUtils.getDataSource());  
  73.         String sql = "select id,name,description from role where id=?";  
  74.         Object[] params = { id };  
  75.         try {  
  76.             Role role = (Role) runner.query(sql, new BeanHandler(Role.class),  
  77.                     params);  
  78.             sql = "select p.id,p.name,p.description from permission p,permission_role pr where p.id=pr.permission_id and pr.role_id=?";  
  79.             params = new Object[] { id };  
  80.             Set<Permission> set = new HashSet<Permission>();  
  81.             set.addAll((List<Permission>) runner.query(sql,  
  82.                     new BeanListHandler(Permission.class), params));  
  83.             role.setPermissions(set);  
  84.             return role;  
  85.         } catch (SQLException e) {  
  86.             throw&nbs
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。