权限管理 订阅
权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少。权限管理几乎出现在任何系统里面,只要有用户和密码的系统。 很多人常将“用户身份认证”、“密码加密”、“系统管理”等概念与权限管理概念混淆。 展开全文
权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少。权限管理几乎出现在任何系统里面,只要有用户和密码的系统。 很多人常将“用户身份认证”、“密码加密”、“系统管理”等概念与权限管理概念混淆。
信息
规    则
根据系统设置的安全规则
认    证
用户和密码的系统
分    类
身份认证”、“密码加密”
中文名
权限管理
外文名
authority management
权限管理场景举例
企业IT管理员一般都能为系统定义角色,给用户分配角色。这就是最常见的基于角色访问控制。场景举例:1、给张三赋予“人力资源经理”角色,“人力资源经理”具有“查询员工”、“添加员工”、“修改员工”和“删除员工”权限。此时张三能够进入系统,则可以进行这些操作;2、去掉李四的“人力资源经理”角色,此时李四就不能够进入系统进行这些操作了。以上举例,局限于功能访问权限。还有一些更加丰富、更加细腻的权限管理。比如:1、因为张三是北京分公司的“人力资源经理”,所以他能够也只能够管理北京分公司员工和北京分公司下属的子公司(海淀子公司、朝阳子公司、西城子公司、东城子公司等)的员工;2、因为王五是海淀子公司的“人力资源经理”,所以他能够也只能够管理海淀子公司的员工;3、普通审查员审查财务数据的权限是:在零售行业审核最高限额是¥50万,在钢铁行业最高限额是¥1000万;高级审查员不受该限额限制;4、ATM取款每次取款额不能超过¥5000元,每天取款总额不能超过¥20000元。这些权限管理和数据(可以统称为资源)直接相关,又称为数据级权限管理、细粒度权限管理或者内容权限管理。
收起全文
精华内容
下载资源
问答
  • 微服务化开发平台,具有统一授权、认证后台管理系统,其中包含具备用户管理、资源权限管理等多个模块,支持多业务系统并行开发,可以作为后端服务的开发脚手架。代码简洁,架构清晰,适合学习和直接项目中使用。 ...
  • 3. 掌握基于url的权限管理(不使用Shiro权限框架的情况下实现权限管理) 4. shiro实现用户认证 5. shiro实现用户授权 6. shiro与企业web项目整合开发的方法 权限管理原理知识 什么是权限管理 只要有用户参与的系统一般...

    知识清单

    1.了解基于资源的权限管理方式
    2. 掌握权限数据模型
    3. 掌握基于url的权限管理(不使用Shiro权限框架的情况下实现权限管理)
    4. shiro实现用户认证
    5. shiro实现用户授权
    6. shiro与企业web项目整合开发的方法

    权限管理原理知识

    什么是权限管理

    只要有用户参与的系统一般都要有权限管理,权限管理实现对用户访问系统的控制。按照安全规则或安全策略控制用户可以访问而且只能访问自己被授权的资源。
    权限管理包括用户认证和用户授权两部分。

    用户认证

    用户认证概念

    用户认证—— 用户去访问系统,系统需要验证用户身份的合法性。最常用的用户身份认证方法:1.用户密码方式、2.指纹打卡机、3.基于证书的验证方法。系统验证用户身份合法,用户方可访问系统的资源。

    用户认证流程


    关键对象

    subject:主体,理解为用户,可能是程序,都要去访问系统的资源,系统需要对subject进行身份认证。
    principal:身份信息,通常是唯一的,一个主体可以有多个身份信息,但是只能有一个主身份信息(primary  principal)。
    credential:凭证信息,可以是密码、证书、指纹等。
    总结:主体在进行身份认证时需要提供身份信息和凭证信息。

    用户授权

    用户授权概念

    用户授权,简单理解为访问控制,在用户认证通过后,系统对用户访问资源进行控制,当用户具有资源的访问权限方可访问。

    授权流程


    其中橙色为授权流程

    关键对象

    授权的过程可以理解为  who  对 what(which) 进行how操作
    who:主体,即subject,subject在认证通过后,系统进行访问控制。
    what(which):资源(Resource) ,subject必须具备资源访问权限才可以访问该资源。资源包括很多方面比如:用户列表页面、商品修改菜单、商品id为001的商品信息。
    资源分为资源类型和资源实例
    例如系统的用户信息就是资源类型,相当于Java类。
    系统中id为001的用户就是资源实例,相当于new的Java对象。
    how:权限/许可(permission),针对资源的权限或许可,subject必须具有permission方可访问资源,如何访问/操作需要定义permission,权限比如:用户添加、用户添加、商品删除。

    权限模型

    主体(账号、密码)
    资源(资源名称,访问地址)
    权限(权限名称、资源id)
    角色(角色名称)
    角色和权限关系(角色id、权限id)
    如下图:

    通常企业开发中将资源和权限合并为一张权限表,如下:
    资源(资源名称、访问地址)
    权限(权限名称、资源id)
    合并为:
    权限(权限名称、资源名称、资源访问地址)

    上图被称为权限管理的通用模型,不过在企业开发中根据系统自身特点还会对上图进行修改,但是用户、角色、权限、用户角色关系、角色权限关系是必不可少的。

    分配权限

    用户需要分配相应的权限才可以访问相应的资源。权限是对资源的操作许可。
    通常给用户分配资源权限需要将权限信息持久化,比如存储在关系数据库中。
    把用户信息、权限管理、用户分配的权限信息写入到数据库(权限数据模型)。

    权限控制(授权核心)

    基于角色的访问控制

    RBAC (Role  based access  control) 基于角色的访问控制
    比如:
    系统角色包括:部门经理、总经理...(角色针对用户进行划分)
    系统中代码实现:
    //如果该user是部门经理则可以访问if中的代码
    if(user.getRole("部门经理")){
        // 系统资源内容
        // 用户报表查看
    }
    问题:
    角色是针对人进行划分的,人作为用户在系统中属于活动内容,如果该角色可以访问的资源出现变更,则需要修改代码,比如:需要变更为部门经理和总经理都可以进行用户报表查看,代码改为:
    if(user.getRole("部门经理") || user.getRole("总经理")){
        // 系统资源内容
        // 用户报表查看
    }
    由此可以发现基于角色的访问控制是不利于系统维护的(可扩展性不强)

    基于资源的访问控制

    RBAC (Resource  based  access control)  基于资源的访问控制
    资源在系统中是不变的,比如资源有:类中的方法,页面中的按钮
    对资源的访问需要具有permission权限,代码可以写为:
    if(user.hasPermission("用户报表查看(权限标识符)")){
        // 系统资源内容
        // 用户报表查看
    }
    上面的方法就可以解决用户角色变更而不用修改上边权限控制的代码。
    如果需要变更权限只需要在分配权限模块去操作,给部门经理或总经理增加或解除权限
    建议使用基于资源的访问控制实现权限管理。

    权限管理解决方案

    什么是粗粒度权限和细粒度权限?

    粗粒度权限管理,是对资源类型的管理,资源类型比如:菜单、url连接、用户添加页面、用户信息、类方法、页面中按钮。
    粗粒度权限管理比如:超级管理员可以访问用户添加页面、用户信息等全部页面。
    部门管理员可以访问用户信息页面,包括页面中所有按钮。

    细粒度的权限管理,对资源实例的权限管理。资源实例就是资源类型的具体化,比如:用户id为001的修改连接,1110班的用户信息、行政部的员工。
    细粒度的权限管理就是数据级别的权限管理。
    细粒度权限管理比如:部门经理只可以访问本部门的员工信息,用户只可以看到自己的菜单,大区经理只能查看本辖区的销售订单...

    粗粒度和细粒度例子:
    系统中有一个用户查询页面,对用户列表查询分权限,如粗粒度管理,张三和李四都有用户列表查询的权限,张三和李四都可以访问用户列表查询。
    进一步进行细粒度的管理,张三(行政部)和李四(开发部)只可以查询自己本部门的用户信息,张三只能查看行政部的用户信息,李四只能查询开发部门的用户信息。细粒度的权限管理就是数据级别的权限管理。

    如何实现粗粒度和细粒度的权限管理

    如何实现粗粒度的权限管理?
    粗粒度权限管理比较容易将权限管理代码抽取出来在系统架构级别统一管理。比如:通过SpringMVC的拦截器实现授权。
    如何实现细粒度的权限管理?
    对细粒度的权限管理在数据级别是没有共性可言的,针对细粒度的权限管理就是系统业务逻辑的一部分,如果在业务层去处理相对简单,如果将细粒度的权限管理统一在系统架构级别去抽取,比较困难,即使进行了抽取,功能也可能存在扩展性不全的弊端。建议细粒度权限管理放在业务层去控制。比如:部门经理只查询本部门员工信息,在Service接口提供一个部门id的参数,controller中根据当前用户信息得到该用户属于哪个部门,调用service时将部门id传入service,实现该用户只查询本部门的员工。

    基于url拦截的方式实现

    基于url拦截的方式实现在实际开发中是比较常用的一种方式。
    对于web系统,通过filter过滤器实现url拦截,也可以通过SpringMVC的拦截器实现基于URL的拦截。

    使用权限管理框架来实现

    对于粗粒度的权限管理,建议使用优秀的权限管理框架进行实现,节省开发成本,提高开发效率。
    Shiro就是一个优秀的权限管理框架。

    基于URL的权限管理

    基于url的权限管理流程



    搭建环境

    数据库

    MySQL数据库中创建表:用户表、角色表、权限表(实质是权限和资源的结合)、用户角色关系表、角色权限关系表

    新建数据库shiro, 为了节约测试时间,在SpringMVC+mybatis基础之上进行整合(导入以前的基本数据),并导入权限数据如下:

    有关权限的SQL脚本如下:
    shiro_sql_table.sql
    /*
    SQLyog v10.2 
    MySQL - 5.1.72-community : Database - shiro
    *********************************************************************
    */
    
    
    /*!40101 SET NAMES utf8 */;
    
    /*!40101 SET SQL_MODE=''*/;
    
    /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
    /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
    /*Table structure for table `sys_permission` */
    
    CREATE TABLE `sys_permission` (
      `id` bigint(20) NOT NULL COMMENT '主键',
      `name` varchar(128) NOT NULL COMMENT '资源名称',
      `type` varchar(32) NOT NULL COMMENT '资源类型:menu,button,',
      `url` varchar(128) DEFAULT NULL COMMENT '访问url地址',
      `percode` varchar(128) DEFAULT NULL COMMENT '权限代码字符串',
      `parentid` bigint(20) DEFAULT NULL COMMENT '父结点id',
      `parentids` varchar(128) DEFAULT NULL COMMENT '父结点id列表串',
      `sortstring` varchar(128) DEFAULT NULL COMMENT '排序号',
      `available` char(1) DEFAULT NULL COMMENT '是否可用,1:可用,0不可用',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    /*Table structure for table `sys_role` */
    
    CREATE TABLE `sys_role` (
      `id` varchar(36) NOT NULL,
      `name` varchar(128) NOT NULL,
      `available` char(1) DEFAULT NULL COMMENT '是否可用,1:可用,0不可用',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    /*Table structure for table `sys_role_permission` */
    
    CREATE TABLE `sys_role_permission` (
      `id` varchar(36) NOT NULL,
      `sys_role_id` varchar(32) NOT NULL COMMENT '角色id',
      `sys_permission_id` varchar(32) NOT NULL COMMENT '权限id',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    /*Table structure for table `sys_user` */
    
    CREATE TABLE `sys_user` (
      `id` varchar(36) NOT NULL COMMENT '主键',
      `usercode` varchar(32) NOT NULL COMMENT '账号',
      `username` varchar(64) NOT NULL COMMENT '姓名',
      `password` varchar(32) NOT NULL COMMENT '密码',
      `salt` varchar(64) DEFAULT NULL COMMENT '盐',
      `locked` char(1) DEFAULT NULL COMMENT '账号是否锁定,1:锁定,0未锁定',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    /*Table structure for table `sys_user_role` */
    
    CREATE TABLE `sys_user_role` (
      `id` varchar(36) NOT NULL,
      `sys_user_id` varchar(32) NOT NULL,
      `sys_role_id` varchar(32) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
    /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
    
    shiro_sql_table_data.sql
    /*
    SQLyog v10.2 
    MySQL - 5.1.72-community : Database - shiro
    *********************************************************************
    */
    
    
    /*!40101 SET NAMES utf8 */;
    
    /*!40101 SET SQL_MODE=''*/;
    
    /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
    /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
    /*Data for the table `sys_permission` */
    
    insert  into `sys_permission`(`id`,`name`,`type`,`url`,`percode`,`parentid`,`parentids`,`sortstring`,`available`) values 
    (1,'权限','','',NULL,0,'0/','0','1'),(11,'商品管理','menu','/item/queryItem.action',NULL,1,'0/1/','1.','1'),
    (12,'商品新增','permission','/item/add.action','item:create',11,'0/1/11/','','1'),
    (13,'商品修改','permission','/item/editItem.action','item:update',11,'0/1/11/','','1'),
    (14,'商品删除','permission','','item:delete',11,'0/1/11/','','1'),
    (15,'商品查询','permission','/item/queryItem.action','item:query',11,'0/1/15/',NULL,'1'),
    (21,'用户管理','menu','/user/query.action','user:query',1,'0/1/','2.','1'),
    (22,'用户新增','permission','','user:create',21,'0/1/21/','','1'),
    (23,'用户修改','permission','','user:update',21,'0/1/21/','','1'),
    (24,'用户删除','permission','','user:delete',21,'0/1/21/','','1');
    
    /*Data for the table `sys_role` */
    
    insert  into `sys_role`(`id`,`name`,`available`) values 
    	('ebc8a441-c6f9-11e4-b137-0adc305c3f28','商品管理员','1'),
    	('ebc9d647-c6f9-11e4-b137-0adc305c3f28','用户管理员','1');
    
    /*Data for the table `sys_role_permission` */
    
    insert  into `sys_role_permission`(`id`,`sys_role_id`,`sys_permission_id`) values 
    	('ebc8a441-c6f9-11e4-b137-0adc305c3f21','ebc8a441-c6f9-11e4-b137-0adc305c','12'),
    	('ebc8a441-c6f9-11e4-b137-0adc305c3f22','ebc8a441-c6f9-11e4-b137-0adc305c','11'),
    	('ebc8a441-c6f9-11e4-b137-0adc305c3f24','ebc9d647-c6f9-11e4-b137-0adc305c','21'),
    	('ebc8a441-c6f9-11e4-b137-0adc305c3f25','ebc8a441-c6f9-11e4-b137-0adc305c','15'),
    	('ebc9d647-c6f9-11e4-b137-0adc305c3f23','ebc9d647-c6f9-11e4-b137-0adc305c','22'),
    	('ebc9d647-c6f9-11e4-b137-0adc305c3f26','ebc8a441-c6f9-11e4-b137-0adc305c','13');
    
    /*Data for the table `sys_user` */
    
    insert  into `sys_user`(`id`,`usercode`,`username`,`password`,`salt`,`locked`) values 
    	('lisi','lisi','李四','bf07fd8bbc73b6f70b8319f2ebb87483','uiwueylm','0'),
    	('zhangsan','zhangsan','张三','cb571f7bd7a6f73ab004a70322b963d5','eteokues','0');
    
    /*Data for the table `sys_user_role` */
    
    insert  into `sys_user_role`(`id`,`sys_user_id`,`sys_role_id`) values 
    	('ebc8a441-c6f9-11e4-b137-0adc305c3f28','zhangsan','ebc8a441-c6f9-11e4-b137-0adc305c'),
    	('ebc9d647-c6f9-11e4-b137-0adc305c3f28','lisi','ebc9d647-c6f9-11e4-b137-0adc305c');
    
    /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
    /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
    查看对应权限模型的数据如下:
    sys_user  用户表数据

    sys_role  角色表

    sys_permission 权限表

    sys_user_role  用户角色关系表

    sys_role_permission  角色权限关系表

    开发环境

    JDK1.8
    MyEclipse
    技术架构:SpringMVC+Mybatis+jQuery easyUI

    系统工程架构


    系统登录

    系统登录相当于用户身份认证,用户登录成功,要在Session中记录用户的身份信息。
    操作流程:
    用户进入登录页面。
    输入用户名和密码进行登陆。
    进行用户名和密码校验。
    如果校验通过,在Session中记录用户身份信息。

    用户的身份信息

    创建专门类用于记录用户身份信息。
    /**
     * 用户身份信息,存入Session  由于Tomcat正常关闭时会将Session序列化的本地硬盘上,所以实现Serializable接口
     * @author liuxun
     *
     */
    public class ActiveUser implements Serializable {
    	private String userid; //用户id(主键)
    	private String usercode; // 用户账号
    	private String username; // 用户姓名
    	....
            ....
    }

    mapper

    mapper接口:根据用户账号查询用户(sys_user)信息 (使用逆向工程生成权限相关的PO类和mapper接口)
    如下所示:
      
    将生成的代码拷贝到项目中

    service(进行用户名和密码校验)

    接口功能:根据用户的身份和密码进行认证,如果认证通过,返回用户身份信息。
    认证过程:
    根据用户身份(账号)查询数据库,如果查询不到 则抛出用户不存在
    对输入的密码和数据库密码进行比对,如果一致,认证通过。
    新建权限管理Service接口 添加身份认证方法
    /**
     * 认证授权服务接口
     * @author liuxun
     *
     */
    public interface SysService {
    	//根据用户的身份和密码进行认证,如果认证通过,返回用户身份信息
    	public ActiveUser authenticat(String usercode,String password) throws Exception;
    	
    	//根据用户账号查询用户信息
    	public SysUser findSysUserByUserCode(String userCode) throws Exception;
            ......
    }
    方法实现:
    public class SysServiceImpl implements SysService {
    	@Autowired
    	private SysUserMapper sysUserMapper;
    
    	public ActiveUser authenticat(String usercode, String password) throws Exception {
    
    		/**
    		 * 认证过程: 根据用户身份(账号)查询数据库,如果查询不到则用户不存在 
    		 * 对输入的密码和数据库密码进行比对,如果一致则认证通过
    		 */
    		// 根据用户账号查询数据库
    		SysUser sysUser = this.findSysUserByUserCode(usercode);
    
    		if (sysUser == null) {
    			// 抛出异常
    			throw new CustomException("用户账号不存在");
    		}
    
    		// 数据库密码(MD5加密后的密码)
    		String password_db = sysUser.getPassword();
    
    		// 对输入的密码和数据库密码进行比对,如果一致,认证通过
    		// 对页面输入的密码进行MD5加密
    		String password_input_md5 = new MD5().getMD5ofStr(password);
    		if (!password_db.equalsIgnoreCase(password_input_md5)) {
    			//抛出异常
    			throw new CustomException("用户名或密码错误");
    		}
    		//得到用户id
    		String userid = sysUser.getId();
    		
    		//认证通过,返回用户身份信息
    		ActiveUser activeUser = new ActiveUser();
    		activeUser.setUserid(userid);
    		activeUser.setUsercode(usercode);
    		activeUser.setUsername(sysUser.getUsername());
    
    		return activeUser;
    	}
    
    	public SysUser findSysUserByUserCode(String userCode) throws Exception {
    		SysUserExample sysUserExample = new SysUserExample();
    		SysUserExample.Criteria criteria = sysUserExample.createCriteria();
    		criteria.andUsercodeEqualTo(userCode);
    
    		List<SysUser> list = sysUserMapper.selectByExample(sysUserExample);
    		if (list != null && list.size() > 0) {
    			return list.get(0);
    		}
    
    		return null;
    	}
       
           ......
    }
    配置Service,往类Service中使用@Autowire 需要注册Service 注册有两种方法(注解或配置文件),在架构时没有配置扫描Service  需要在配置文件中注册Service
    <!-- 认证和授权的Service -->
       <bean id="sysService" class="liuxun.ssm.service.impl.SysServiceImpl"></bean>

    controller(记录Session)

    //用户登录提交方法
    	@RequestMapping("/login")
    	public String login(HttpSession session,String randomcode,String usercode,String password) throws Exception{
    		// 校验验证码,防止恶性攻击
    		// 从Session中获取正确的验证码
    		String validateCode = (String) session.getAttribute("validateCode");
    		
    		//输入的验证码和Session中的验证码进行对比
    		if (!randomcode.equalsIgnoreCase(validateCode)) {
    			//抛出异常
    			throw new CustomException("验证码输入错误");
    		}
    		
    		//调用Service校验用户账号和密码的正确性
    		ActiveUser activeUser = sysService.authenticat(usercode, password);
    		
    		//如果Service校验通过,将用户身份记录到Session
    		session.setAttribute("activeUser", activeUser);
    		//重定向到商品查询页面
    		return "redirect:/first.action";
    	}

    用户认证拦截器

    anonymousURL.properties配置匿名URL

    配置可以匿名访问的URL


    编写身份认证拦截器

    //用于用户认证校验、用户权限校验
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            
    		//得到请求的url
    		String url = request.getRequestURI();
    		
    		//判断是否是公开地址
    		//实际开发中需要将公开地址配置在配置文件中
    		//从配置文件中取出可以匿名访问的URL
    		List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
    		for (String open_url : open_urls) {
    			if (url.indexOf(open_url)>=0) {
    				//如果是公开地址 则放行
    				return true;
    			}
    		}
    		
    		//判断用户身份在Session中是否存在
    		HttpSession session = request.getSession();
    		ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
    		//如果用户身份在session中存在则放行
    		if (activeUser!=null) {
    			return true;
    		}
    		//执行到这里拦截,跳转到登录页面,用户进行身份认证
    		request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
    		
    		//如果返回false表示拦截器不继续执行handler,如果返回true表示放行
    		return false;
    	}

    配置认证拦截器

    <!-- 拦截器 -->
    	<mvc:interceptors>
    	    <mvc:interceptor>
    		   	<!-- 用户认证拦截 -->
    		   	<mvc:mapping path="/**"/>
    		   	<bean class="liuxun.ssm.controller.interceptor.LoginInterceptor"></bean>
    	    </mvc:interceptor>
    	</mvc:interceptors>

    用户授权

    commonURL.properties配置公用访问地址

    在此配置文件中配置公用访问地址,公用访问地址只需要通过用户认证,不需要对公用访问地址分配权限即可访问。

    获取用户权限范围的菜单

    思路:
    在用户认证时,认证通过,根据用户id从数据库获取用户权限范围内的菜单,将菜单的集合存储在Session中。
    编辑存储用户身份信息的类ActiveUser 如下所示:
    public class ActiveUser implements Serializable {
    	private String userid; //用户id(主键)
    	private String usercode; // 用户账号
    	private String username; // 用户姓名
    	
    	private List<SysPermission> menus; //菜单
            //......setter和getter方法
    }
    自定义权限Mapper
    因为使用逆向工程生成的Mapper是不建议去修改的 因为它的代码联系非常紧密,一旦修改错误 就会牵一发而动全身。所以需要自定义一个权限的Mapper(SysPermissionMapperCustom)
    SysPermissionMapperCustom.xml中添加根据用户id查询用户权限的菜单
    <!-- 根据用户id查询菜单 -->
    <select id="findMenuListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
       SELECT 
    	  * 
    	FROM
    	  sys_permission 
    	WHERE TYPE = 'menu' 
    	  AND id IN 
    	  (SELECT 
    	    sys_permission_id 
    	  FROM
    	    sys_role_permission 
    	  WHERE sys_role_id IN 
    	    (SELECT 
    	      sys_role_id 
    	    FROM
    	      sys_user_role 
    	    WHERE sys_user_id = #{userid}))
    </select>
    SysPermissionMapperCustom .java接口中添加对应的方法
    public interface SysPermissionMapperCustom {
        //根据用户id查询菜单
    	public List<SysPermission> findMenuListByUserId(String userid) throws Exception;
      .......
    }
    在权限Service接口中添加对应的方法 在实现中注入SysPermissionMapperCustom
    SysServiceImpl.java中添加如下内容
    @Override
    	public List<SysPermission> findMenuListByUserId(String userid) throws Exception {
    		return sysPermissionMapperCustom.findMenuListByUserId(userid);
    	}

    获取用户权限范围的URL

    思路:
    在用户认证时,认证通过后,根据用户id从数据库中获取用户权限范围的URL,将URL的集合存储在Session中。
    修改ActiveUser 添加URL的权限集合
    public class ActiveUser implements Serializable {
    	private String userid; //用户id(主键)
    	private String usercode; // 用户账号
    	private String username; // 用户姓名
    	
    	private List<SysPermission> menus; //菜单
    	private List<SysPermission> permissions; //权限
    	//...setter和getter方法
    }
    SysPermissionMapperCustom .xml中添加根据用户id查询用户权限的URL
    <!-- 根据用户id查询URL -->
    <select id="findPermissionListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
       SELECT 
    	  * 
    	FROM
    	  sys_permission 
    	WHERE TYPE = 'permission' 
    	  AND id IN 
    	  (SELECT 
    	    sys_permission_id 
    	  FROM
    	    sys_role_permission 
    	  WHERE sys_role_id IN 
    	    (SELECT 
    	      sys_role_id 
    	    FROM
    	      sys_user_role 
    	    WHERE sys_user_id = #{userid}))
    </select>
    SysPermissionMapperCustom .java接口中添加对应的方法
    //根据用户id查询权限URL
    	public List<SysPermission> findPermissionListByUserId(String userid) throws Exception;
    SysServiceImpl.java中添加如下内容
    @Override
    	public List<SysPermission> findPermissionListByUserId(String userid) throws Exception {
    		return sysPermissionMapperCustom.findPermissionListByUserId(userid);
    	}

    用户认证通过后取出菜单和URL放入Session

    修改权限SysServiceImpl中用户认证方法的代码
    //得到用户id
    		String userid = sysUser.getId();
    		//根据用户id查询菜单
    		List<SysPermission> menus = this.findMenuListByUserId(userid);
    		//根据用户id查询权限url
    		List<SysPermission> permissions = this.findPermissionListByUserId(userid);
    		
    		//认证通过,返回用户身份信息
    		ActiveUser activeUser = new ActiveUser();
    		activeUser.setUserid(userid);
    		activeUser.setUsercode(usercode);
    		activeUser.setUsername(sysUser.getUsername());
    		
            //放入权限范围的菜单和url
    		activeUser.setMenus(menus);
    		activeUser.setPermissions(permissions);

    菜单动态显示

    <c:if test="${activeUser.menus!=null }">
    				<ul>
    				<c:forEach items="${activeUser.menus }" var="menu">
    					<li><div>
    						<a title="${menu.name }" ref="1_1" href="#"
    							rel="${baseurl }/${menu.url }" icon="icon-log"><span
    							class="icon icon-log"> </span><span class="nav"><a href=javascript:addTab('${menu.name }','${baseurl }/${menu.url }')>${menu.name }</a></span></a>
    					</div></li>
    				</c:forEach>
    				</ul>
    			</c:if>

    授权拦截器

    public class PermissionInterceptor implements HandlerInterceptor{
    	//在执行handler之前执行的
    	//用于用户认证校验、用户权限校验
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            
    		//得到请求的url
    		String url = request.getRequestURI();
    		
    		//判断是否是公开地址
    		//实际开发中需要将公开地址配置在配置文件中
    		//从配置文件中取出可以匿名访问的URL
    		List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
    		for (String open_url : open_urls) {
    			if (url.indexOf(open_url)>=0) {
    				//如果是公开地址 则放行
    				return true;
    			}
    		}
    		
    		//从配置文件中获取公用访问url
    		List<String> common_urls = ResourcesUtil.getKeyList("commonURL");
    		//遍历公用地址 如果是公开地址则放行
    		for (String common_url : common_urls) {
    			if (url.indexOf(common_url)>0) {
    				//如果是公开,则放行
    				return true;
    			}
    		}
    		
    		//判断用户身份在Session中是否存在
    		HttpSession session = request.getSession();
    		ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
    		//从Session中取出权限范围的URL
    		List<SysPermission> permissions = activeUser.getPermissions();
    		for (SysPermission sysPermission : permissions) {
    			//权限url
    			String permission_url = sysPermission.getUrl();
    			if (url.indexOf(permission_url)>0) {
    				return true;
    			}
    		}
    		
    		//执行到这里拦截,跳转到无权访问的提示页面
    		request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response);
    		
    		//如果返回false表示拦截器不继续执行handler,如果返回true表示放行
    		return false;
    	}
       ......
    }

    配置授权拦截器

    注意:要将授权拦截器配置在用户认证拦截器的下边,这是因为SpringMVC拦截器的放行方法是顺序执行的,如果是Struts的话则正好相反。
    <!-- 拦截器 -->
    	<mvc:interceptors>
    	    <mvc:interceptor>
    		   	<!-- 用户认证拦截 -->
    		   	<mvc:mapping path="/**"/>
    		   	<bean class="liuxun.ssm.controller.interceptor.LoginInterceptor"></bean>
    	    </mvc:interceptor>
    	    <mvc:interceptor>
    	    	<!-- 资源拦截 -->
    	    	<mvc:mapping path="/**"/>
    	    	<bean class="liuxun.ssm.controller.interceptor.PermissionInterceptor"></bean>
    	    </mvc:interceptor>
    	</mvc:interceptors>
    运行测试:
    其关键代码如下:
    PO类ActiveUser.java 存放用户身份和权限信息的类
    package liuxun.ssm.po;
    
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * 用户身份信息,存入Session  由于Tomcat正常关闭时会将Session序列化的本地硬盘上,所以实现Serializable接口
     * @author liuxun
     *
     */
    public class ActiveUser implements Serializable {
    	private static final long serialVersionUID = 1L;
    	
    	private String userid; //用户id(主键)
    	private String usercode; // 用户账号
    	private String username; // 用户姓名
    	
    	private List<SysPermission> menus; //菜单
    	private List<SysPermission> permissions; //权限
        // 提供对应setter和getter方法
        ......
    }
    自定义权限的Mapper 
    SysPermissionMapperCustom.java
    package liuxun.ssm.mapper;
    
    import java.util.List;
    import liuxun.ssm.po.SysPermission;
    import liuxun.ssm.po.SysPermissionExample;
    import org.apache.ibatis.annotations.Param;
    /**
     * 权限mapper
     * @author liuxun
     *
     */
    public interface SysPermissionMapperCustom {
        //根据用户id查询菜单
    	public List<SysPermission> findMenuListByUserId(String userid) throws Exception;
    	//根据用户id查询权限URL
    	public List<SysPermission> findPermissionListByUserId(String userid) throws Exception;
    }
    SysPermissionMapperCustom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="liuxun.ssm.mapper.SysPermissionMapperCustom">
    
    <!-- 根据用户id查询菜单 -->
    <select id="findMenuListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
       SELECT 
    	  * 
    	FROM
    	  sys_permission 
    	WHERE TYPE = 'menu' 
    	  AND id IN 
    	  (SELECT 
    	    sys_permission_id 
    	  FROM
    	    sys_role_permission 
    	  WHERE sys_role_id IN 
    	    (SELECT 
    	      sys_role_id 
    	    FROM
    	      sys_user_role 
    	    WHERE sys_user_id = #{userid}))
    </select>
    <!-- 根据用户id查询URL -->
    <select id="findPermissionListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
       SELECT 
    	  * 
    	FROM
    	  sys_permission 
    	WHERE TYPE = 'permission' 
    	  AND id IN 
    	  (SELECT 
    	    sys_permission_id 
    	  FROM
    	    sys_role_permission 
    	  WHERE sys_role_id IN 
    	    (SELECT 
    	      sys_role_id 
    	    FROM
    	      sys_user_role 
    	    WHERE sys_user_id = #{userid}))
    </select>
    </mapper>
    自定义权限的Service接口以及实现类
    SysService.java
    package liuxun.ssm.service;
    
    import java.util.List;
    
    import liuxun.ssm.po.ActiveUser;
    import liuxun.ssm.po.SysPermission;
    import liuxun.ssm.po.SysUser;
    
    /**
     * 认证授权服务接口
     * @author liuxun
     *
     */
    public interface SysService {
    	//根据用户的身份和密码进行认证,如果认证通过,返回用户身份信息
    	public ActiveUser authenticat(String usercode,String password) throws Exception;
    	
    	//根据用户账号查询用户信息
    	public SysUser findSysUserByUserCode(String userCode) throws Exception;
    	
    	//根据用户id查询权限范围内的菜单
    	public List<SysPermission> findMenuListByUserId(String userid) throws Exception;
    	
    	//根据用户id查询权限范围内的url
    	public List<SysPermission> findPermissionListByUserId(String userid) throws Exception;
    }
    
    SysServiceImpl.java
    package liuxun.ssm.service.impl;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import liuxun.ssm.exception.CustomException;
    import liuxun.ssm.mapper.SysPermissionMapperCustom;
    import liuxun.ssm.mapper.SysUserMapper;
    import liuxun.ssm.po.ActiveUser;
    import liuxun.ssm.po.SysPermission;
    import liuxun.ssm.po.SysUser;
    import liuxun.ssm.po.SysUserExample;
    import liuxun.ssm.service.SysService;
    import liuxun.ssm.util.MD5;
    
    public class SysServiceImpl implements SysService {
    	@Autowired
    	private SysUserMapper sysUserMapper;
    	
    	@Autowired
    	private SysPermissionMapperCustom sysPermissionMapperCustom;
    
    	public ActiveUser authenticat(String usercode, String password) throws Exception {
    
    		/**
    		 * 认证过程: 根据用户身份(账号)查询数据库,如果查询不到则用户不存在 
    		 * 对输入的密码和数据库密码进行比对,如果一致则认证通过
    		 */
    		// 根据用户账号查询数据库
    		SysUser sysUser = this.findSysUserByUserCode(usercode);
    
    		if (sysUser == null) {
    			// 抛出异常
    			throw new CustomException("用户账号不存在");
    		}
    
    		// 数据库密码(MD5加密后的密码)
    		String password_db = sysUser.getPassword();
            
    		// 对输入的密码和数据库密码进行比对,如果一致,认证通过
    		// 对页面输入的密码进行MD5加密
    		String password_input_md5 = new MD5().getMD5ofStr(password);
    		if (!password_db.equalsIgnoreCase(password_input_md5)) {
    			//抛出异常
    			throw new CustomException("用户名或密码错误");
    		}
    		//得到用户id
    		String userid = sysUser.getId();
    		//根据用户id查询菜单
    		List<SysPermission> menus = this.findMenuListByUserId(userid);
    		//根据用户id查询权限url
    		List<SysPermission> permissions = this.findPermissionListByUserId(userid);
    		
    		//认证通过,返回用户身份信息
    		ActiveUser activeUser = new ActiveUser();
    		activeUser.setUserid(userid);
    		activeUser.setUsercode(usercode);
    		activeUser.setUsername(sysUser.getUsername());
    		
            //放入权限范围的菜单和url
    		activeUser.setMenus(menus);
    		activeUser.setPermissions(permissions);
    		
    		return activeUser;
    	}
    
    	public SysUser findSysUserByUserCode(String userCode) throws Exception {
    		SysUserExample sysUserExample = new SysUserExample();
    		SysUserExample.Criteria criteria = sysUserExample.createCriteria();
    		criteria.andUsercodeEqualTo(userCode);
    
    		List<SysUser> list = sysUserMapper.selectByExample(sysUserExample);
    		if (list != null && list.size() > 0) {
    			return list.get(0);
    		}
    
    		return null;
    	}
    	
    	@Override
    	public List<SysPermission> findMenuListByUserId(String userid) throws Exception {
    		return sysPermissionMapperCustom.findMenuListByUserId(userid);
    	}
    
    	@Override
    	public List<SysPermission> findPermissionListByUserId(String userid) throws Exception {
    		return sysPermissionMapperCustom.findPermissionListByUserId(userid);
    	}
    }
    登录控制器
    package liuxun.ssm.controller;
    
    import javax.servlet.http.HttpSession;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import liuxun.ssm.exception.CustomException;
    import liuxun.ssm.po.ActiveUser;
    import liuxun.ssm.service.SysService;
    
    /**
     * 登录和退出
     * @author liuxun
     *
     */
    @Controller
    public class LoginController {
        @Autowired
        private SysService sysService;
    	
    	//用户登录提交方法
    	@RequestMapping("/login")
    	public String login(HttpSession session,String randomcode,String usercode,String password) throws Exception{
    		// 校验验证码,防止恶性攻击
    		// 从Session中获取正确的验证码
    		String validateCode = (String) session.getAttribute("validateCode");
    		
    		//输入的验证码和Session中的验证码进行对比
    		if (!randomcode.equalsIgnoreCase(validateCode)) {
    			//抛出异常
    			throw new CustomException("验证码输入错误");
    		}
    		
    		//调用Service校验用户账号和密码的正确性
    		ActiveUser activeUser = sysService.authenticat(usercode, password);
    		
    		//如果Service校验通过,将用户身份记录到Session
    		session.setAttribute("activeUser", activeUser);
    		//重定向到商品查询页面
    		return "redirect:/first.action";
    	}
    	
    	//用户退出
    	@RequestMapping("/logout")
    	public String logout(HttpSession session) throws Exception{
    		//session失效
    		session.invalidate();
    		//重定向到商品查询页面
    		return "redirect:/first.action";
    	}
    }
    身份认证拦截器LoginInterceptor.java
    package liuxun.ssm.controller.interceptor;
    
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import liuxun.ssm.po.ActiveUser;
    import liuxun.ssm.util.ResourcesUtil;
    
    /**
     * 测试拦截器1
     * @author liuxun
     *
     */
    public class LoginInterceptor implements HandlerInterceptor{
    	//在执行handler之前执行的
    	//用于用户认证校验、用户权限校验
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            
    		//得到请求的url
    		String url = request.getRequestURI();
    		
    		//判断是否是公开地址
    		//实际开发中需要将公开地址配置在配置文件中
    		//从配置文件中取出可以匿名访问的URL
    		List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
    		for (String open_url : open_urls) {
    			if (url.indexOf(open_url)>=0) {
    				//如果是公开地址 则放行
    				return true;
    			}
    		}
    		
    		//判断用户身份在Session中是否存在
    		HttpSession session = request.getSession();
    		ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
    		//如果用户身份在session中存在则放行
    		if (activeUser!=null) {
    			return true;
    		}
    		//执行到这里拦截,跳转到登录页面,用户进行身份认证
    		request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
    		
    		//如果返回false表示拦截器不继续执行handler,如果返回true表示放行
    		return false;
    	}
    
    	//在执行handler返回modelAndView之前执行
    	//如果需要向页面提供一些公用的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
    	@Override
    	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    			throws Exception {
    		System.out.println("HandlerInterceptor2...postHandle");
    	}
    
    	//执行handler之后执行此方法
    	//作为系统统一异常处理,进行方法执行性能监控,在preHandler中设置一个时间点 在afterCompletion设置一个时间点 二者时间差就是执行时长
    	//实现系统,统一日志记录
    	@Override
    	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception modelAndView)
    			throws Exception {
    		System.out.println("HandlerInterceptor2...afterCompletion");
    	}
    
    }
    资源授权拦截器PermissionInterceptor
    package liuxun.ssm.controller.interceptor;
    
    import java.security.acl.Permission;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import liuxun.ssm.po.ActiveUser;
    import liuxun.ssm.po.SysPermission;
    import liuxun.ssm.util.ResourcesUtil;
    
    /**
     * 授权拦截器
     * @author liuxun
     *
     */
    public class PermissionInterceptor implements HandlerInterceptor{
    	//在执行handler之前执行的
    	//用于用户认证校验、用户权限校验
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            
    		//得到请求的url
    		String url = request.getRequestURI();
    		
    		//判断是否是公开地址
    		//实际开发中需要将公开地址配置在配置文件中
    		//从配置文件中取出可以匿名访问的URL
    		List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
    		for (String open_url : open_urls) {
    			if (url.indexOf(open_url)>=0) {
    				//如果是公开地址 则放行
    				return true;
    			}
    		}
    		
    		//从配置文件中获取公用访问url
    		List<String> common_urls = ResourcesUtil.getKeyList("commonURL");
    		//遍历公用地址 如果是公开地址则放行
    		for (String common_url : common_urls) {
    			if (url.indexOf(common_url)>0) {
    				//如果是公开,则放行
    				return true;
    			}
    		}
    		
    		//判断用户身份在Session中是否存在
    		HttpSession session = request.getSession();
    		ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
    		//从Session中取出权限范围的URL
    		List<SysPermission> permissions = activeUser.getPermissions();
    		for (SysPermission sysPermission : permissions) {
    			//权限url
    			String permission_url = sysPermission.getUrl();
    			if (url.indexOf(permission_url)>0) {
    				return true;
    			}
    		}
    		
    		//执行到这里拦截,跳转到无权访问的提示页面
    		request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response);
    		
    		//如果返回false表示拦截器不继续执行handler,如果返回true表示放行
    		return false;
    	}
    
    	//在执行handler返回modelAndView之前执行
    	//如果需要向页面提供一些公用的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
    	@Override
    	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    			throws Exception {
    		System.out.println("HandlerInterceptor2...postHandle");
    	}
    
    	//执行handler之后执行此方法
    	//作为系统统一异常处理,进行方法执行性能监控,在preHandler中设置一个时间点 在afterCompletion设置一个时间点 二者时间差就是执行时长
    	//实现系统,统一日志记录
    	@Override
    	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception modelAndView)
    			throws Exception {
    		System.out.println("HandlerInterceptor2...afterCompletion");
    	}
    
    }
    拦截器配置
    <!-- 拦截器 -->
    	<mvc:interceptors>
    	    <mvc:interceptor>
    		   	<!-- 用户认证拦截 -->
    		   	<mvc:mapping path="/**"/>
    		   	<bean class="liuxun.ssm.controller.interceptor.LoginInterceptor"></bean>
    	    </mvc:interceptor>
    	    <mvc:interceptor>
    	    	<!-- 资源拦截 -->
    	    	<mvc:mapping path="/**"/>
    	    	<bean class="liuxun.ssm.controller.interceptor.PermissionInterceptor"></bean>
    	    </mvc:interceptor>
    	</mvc:interceptors>
    使用URL拦截总结:
    使用基于URL拦截的权限管理方式,实现起来比较简单,不依赖框架使用过滤器或拦截器就可以实现
    弊端:需要将所有的URL全部配置起来,比较繁琐,不易维护,URL(资源)和权限表示方式不规范

    展开全文
  • ThinkPHP5.0 php7 Auth权限认证管理模块 , 目前还没有人发THINKPHP5.0用的这个权限认证模块, 自己改造的thinkphp3.2里面用的auth授权验证模块为TP5.0 php7能用的模块,
  • idea开发的springboot项目后端微服务,使用gradle搭建,...权限管理通过shiro认证授权,可以通过nginx配置集成其他微服务,只需要调用应用中的授权接口即可。 api接口说明采用swagger,详情可以参考项目中的Readme文件
  • Android权限管理

    万次阅读 2019-07-17 12:39:52
    Android权限管理(PermissionsDispatcher框架使用)简述一、Android权限二、6.0以上权限管理 简述 由于对于安全考虑,Android对于权限管理更加的严谨,以6.0位界分为两种处理方式:6.0以下系统还是保持旧的处理...

    Android权限管理(PermissionsDispatcher框架使用)

    简述

    由于对于安全考虑,Android对于权限的管理更加的严谨,以6.0位界分为两种处理方式:6.0以下系统还是保持旧的处理方式,直接在AndroidManifest清单中注册相应权限就可以;6.0以上系统就需要根据权限的等级(普通权限和危险权限)进行权限注册,如果是普通权限还是依照之前的处理方式直接在AndroidManifest清单中注册即可,但是危险权限不仅需要在AndroidManifest清单中注册且还需要在使用时动态申请
    其实现在主流权限管理框架有三个,分别为PermissionsDispatcher、RxPermissions和easypermissions;在使用中作者方向从代码简洁及易用性来说PermissionsDispatcher跟优于其他两种两种框架;PermissionsDispatcher是采用注解的方式进行权限管理,RxPermissions是基于RxJava的权限管理,easypermissions是谷歌推出的;有兴趣的朋友加深去了解一下;但不管怎么样这三个框架都简化了需要动态管理的权限。

    一、Android权限

    在这里插入图片描述在这里插入图片描述
    terminal中使用这个命令可以列出调试手机的所有权限,包含应用自定义的权限:

    adb shell pm list permissions
    

    注意:并不是所有的危险权限都能申请,有某些权限系统是默认禁止的,目前暂时没有任何办法获取

    二、6.0以上权限管理

    在介绍该PermissionsDispatcher框架前我简述一下,官方或网上给出的很多注册方式都没问题的,但是对于Android本身的问题(千奇百怪手机,不同品牌对于系统再次定制),有时总会出现由于考虑不周总会出现这样那样的问题会让你焦头烂额的,我也是经过多种尝试,最终觉的还是这个框架还是目前来说最稳定的管理方式;
    介绍:PermissionsDispatcher是一个基于注解、帮助开发者简单处理Android 6.0系统中的运行时权限的开源库、避免开发者编写大量繁琐的样板代码并进行了简化处理。
    开源地址:https://github.com/hotchemi/PermissionsDispatcher
    文档介绍:http://hotchemi.github.io/PermissionsDispatcher/
    下面开始介绍如何在Android studio使用该框架:

    1、添加依赖
    在项目工程下的build.gradle文件中加入对maven仓库依赖引入的支持

    allprojects {
        repositories {
            jcenter()
            mavenCentral()
        }
    }
    

    之后在module下的build.gradle文件中添加两项依赖:

    implementation 'com.github.hotchemi:permissionsdispatcher:2.3.1'
    annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.1'
    

    并将targetSdkVersion设为23(一定要大于等于23),即:targetSdkVersion 23
    2、在Plugins加入PermissionsDispatcher插件
    在Android studio加入PermissionsDispatcher插件有益于你后期快速使用PermissionsDispatcher,可以说几乎于是一键导入;
    第一步在AS File点击Setting进入Setting操作面板

    第二部,在Setting操作面板选择Plugins,在右上角输入框中输入PermissionsDispatcher搜索,并安装,安装后需要重启
    在这里插入图片描述
    3、在工程中使用PermissionsDispatcher插件开始布局Permissions管理
    注意:在使用权限管理框架前,一定要明确一点,一定要Activity/Fragment中使用
    第一步:在需要使用权限管理的Activity/Fragment类中右击如下图,选择Generate -> Generate Runtime Permissions…
    第二步:如下图,在权限管理区域选择相应的权限在这里插入图片描述
    然后在Annotations区域,选择相应的注解,选择的注解同时需要自定义对应的方法名;
    最后点击“Generate”按钮;最好强调移一下点击“Generate”后会有个弹窗,可以选择rebuild,也可以不用,但一定要在生成的方法前使用public,且再次将工程build-》rebuild project一下,结果如下图:
    在这里插入图片描述
    以下为注解说明(注:带注释的方法一定不能private,一定要为public):

    注解是否必须要描述
    @RuntimePermissions在Activity的Class声明此注解,来处理我们的权限
    @NeedsPermission请求的权限成功后执行的方法
    @OnShowRationale在申请权限前解释为什么需要这些权限
    @OnPermissionDenied当用户拒绝授权时将调用该方法
    @OnNeverAskAgain当用户选择了 “不再提醒” 将调用该方法

    a、@RuntimePermissions注解:这是必须使用的注解,用于标注在你想要申请权限的Activity或者Fragment上

    @RuntimePermissions
    public class TestActivity extends UMengBaseActivity {
    

    b、@NeedsPermission注解:这也是必须使用的注解,用于标注在你要获取权限的方法,注解括号里面有参数,传入想要申请的权限。也就是说你获取了相应的权限成功后就会执行这个方法

    @NeedsPermission(Manifest.permission.CAMERA)
    public void NeedsMethod() {
    	
    }
    

    c、@OnShowRationale注解:这个不是必须的注解,用于标注申请权限前需要执行的方法,注解
    括号里面有参数,传入想要申请的权限,而且这个方法还要传入一个PermissionRequest对象,这个对象有两种方法:proceed()让权限请求继续,cancel()让请求中断。也就是说,这个方法会拦截你发出的请求,这个方法用于告诉用户你接下来申请的权限是干嘛的,说服用户给你权限

    @OnShowRationale(Manifest.permission.CAMERA)
    public void RationaleMethod(final PermissionRequest request) {
    
    }
    

    d、@OnPermissionDenied注解:这个也不是必须的注解,用于标注如果权限请求失败,但是用户没有勾选不再询问的时候执行的方法,注解括号里面有参数,传入想要申请的权限。也就是说,我们可以在这个方法做申请权限失败之后的处理,如像用户解释为什么要申请,或者重新申请操作等

    @OnPermissionDenied(Manifest.permission.CAMERA)
    public void DeniedMethod() {
    
     }
    

    e、@OnNeverAskAgain注解:这个也不是必须的注解,用于标注如果权限请求失败,而且用户勾选不再询问的时候执行的方法,注解括号里面有参数,传入想要申请的权限。也就是说,我们可以在这个方法做申请权限失败并选择不再询问之后的处理。例如,可以告诉作者想开启权限的就从手机设置里面开启

    @OnNeverAskAgain(Manifest.permission.CAMERA)
    public void AskMethod() {
    
    }
    

    为什么注解方法前一定要使用public:
    原因是只要我们实现了@RuntimePermissions和@NeedsPermission这两个必须的注解之后,再build一次project之后,编译器就会在在app\build\intermediates\classes\debug目录下与被注解的Activity同一个包下生成一个辅助类,名称为 “被注解的Activity的名称+PermissionsDispatcher” 的辅助类,用来调用被注解的Activity的方法(就是因为这个所以被注解的方法不能private,private方法的作用域不在其他的类)。所以,第一次用的话,要注解好之后,build一次,下面的方法里面的PermissionsDispatcherActivityPermissionsDispatcher才不会令AS报红。

    最后在相应的方法调用申请方法就可以了
    类名:类名+PermissionsDispatcher
    方法名:@NeedsPermission注解的方法名+WithCheck

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        TestActivityPermissionsDispatcher.NeedsMethodWithCheck(this);//调用此方法即可动态申请权限;
    }
    
    展开全文
  • 对于Saas业内在用户统一身份认证及授权管理领域,主要关注 4 个方面(4A管理)): 集中账号管理(Account)、集中认证管理(Authentication)、集中授权管理(Authorization)和集中审计管理(Audit), 简称 4A ...

    对于 Saas业内在用户统一身份认证及授权管理领域,主要关注 4 个方面(4A管理)):
          集中账号管理(Account)、集中认证管理(Authentication)、集中授权管理(Authorization)和集中审计管理(Audit), 简称 4A 管理。
    后来发展了 IAM(Identity and Access Management,即身份识别与访问管理)的相关技术,在云计算等领域应用广泛。整体来说,不管是 4A 还是 IAM 还是未来可能的其他技术方案,都可以归纳为『统一身份治理』的范畴。本文基于『统一身份治理』的概念提出了统一身份管理系统(Unified Identity Management System)的设计思路。

    一、统一身份管理系统(Unified Identity Management System)

          统一身份管理系统(简称 UIMS)可以认是多租户软件架构的升级版,通常是整个平台帐号和权限管控的基础性系统,平台下所有系统的账户管理、身份认证、用户授权、权限控制等行为都必须经由该系统处理,提供帐号密码管理、基本资料管理、角色权限管理等功能。UIMS 基于『统一身份治理』的概念,可划分为两级账户体系、基础权限模块和基础信息模块三大模块。其中两级账户体系将账户分为组织实体帐号和个人实体账户两大类,个人实体从属于组织实体,也可以不从属任何组织实体,且个人实体可同时从属于多个组织实体;基础权限模块将各业务系统的资源权限进行统一管理和授权;基础信息模块用于描述组织实体和个人实体的基本信息,如组织实体名称、地址、法人,个人实体姓名、电话号码、性别等基础信息。UIMS 提供统一的 API 与各子系统连接。

    从整个平台的角度来看,UIMS 除了提供上述功能和服务,还应该满足以下需求:

    编号需求描述
    1软件授权云平台付费授权机制,可按时间、功能、数量等进行付费授权
    2组织入驻允许组织主动申请加入平台
    3实名认证个人实名认证、组织实名认证
    4资质审核个人和组织的资质审核,如对获得的证书或荣誉进行审核
    5组织绑定个人账户绑定组织,与组织建立关联关系
    6组织解绑个人账户与组织进行解绑
    7账户注销个人账户注销,并销毁所有个人资料和档案
    8统一登录即 SSO
    9统一注册提供统一的用户注册页面

    因此,从功能的角度可以将 UIMS 划分为以下模块:

    一)功能
    
        系统设置 System Configuration
          系统标识管理 System Identifiers Management
          服务账户管理 Service Accounts Management
        
        账户实体管理 Account Entities Management
          组织实体管理 Organization Entities Management
          组织架构管理 Organization Management
          个体账户管理 Individual Accounts Management
        
        账户权限管理 Account Permissions Management
          用户组管理 User Group Management
          角色管理 User Roles Management
          资源权限管理 Permission Resources Management
          权限策略组管理 Permission Group Management
        
        认证审核管理 Authentication Management
          个人认证管理 Individual Authentication Management
          组织认证管理 Organization Authentication Management
          资质审核管理 Qualification Management
        
        付费授权管理 Authorization Management
          组织授权管理 Organization Authorization Management
      
    二)页面
    
        统一注册页面 Unified Signup Page
        统一登录页面 Unified Signin Page
        组织入驻页面 Organization Signup Page
        个人实名认证页面 Individual Authentication Page
        组织实名认证页面 Organization Authentication Page
    
    三)API
    
        鉴权相关的APIs
        业务相关的APIs
    

    其中组织绑定和解绑的功能,可以放到『组织实体管理』 或『个体账户管理』的功能中。需要注意的是,组织绑定与解绑功能,是否与业务系统关联,下文将进行阐述。

    二、两级账户体系和基础权限模块

    基于『统一身份治理』的理念,采用两级账户体系(UIMS 提供接口)实现多系统融合的平台级 SAAS。两级账户体系将账户类别分为组织实体和个人实体两类(详见下文用户分类)。个人实体可以从属于组织实体(可以从属于多个组织实体),也可以不从属。个人账户体系和组织账户体系在云平台内享有的权限是不一样的,虽然大部分功能和服务两个体系的实体均可独立使用,互不干扰,但部分功能和服务有所不同。

    1. 基本原则

    平台级 SAAS 模式账户体系应遵循以下几个基本原则:

    • 个人账户统一原则:个人账户一次注册,全平台通用,类似于全网通行证和 SSO,注册和登录都在 UIMS 进行。
    • 业务权限独立原则:每个子系统的权限体系是独立管理的。『个人账户统一原则』明确了账户体系是统一的,但是对于每个子系统而言,每个账户所能使用的功能和服务,所能查看的数据权限是独立维护的,比如 XXX 公司(组织)-研发T3组(用户组)-张三(用户)-研发人员(角色),在 CRM 系统中,拥有的资源权限(详见下文),与其在 OA 系统中的所拥有的资源权限肯定是不一致的。
    • 组织实体隔离原则:不同的组织实体之间,是相互隔离,独立管理的。每个组织实体可以自行组织自己的组织体系、账户体系和权限体系。不同的组织实体资源权限也是隔离的。
    • 从属关系隔离原则:个体账户与组织实体的从属关系是基于单独的业务系统存在的,『个人账户统一原则』明确的仅是个人账户的全网统一,但组织实体、从属关系并没有统一,并且是隔离的。比如在 CRM 系统中,张三(用户)从属于 XXXX 公司(组织),但在 OA 系统中,张三(用户)默认是不从属于任何组织的,从属关系受到具体业务系统的影响。事实上,这个原则是非强制的,具体取决于各自的业务逻辑和业务场景。如果要简化从属关系的管理,那么可以不遵循此原则,即个体账户与组织实体的从属关系是全平台统一的,与业务系统无关,但这会为降低平台的灵活性和扩展性。灵活性和复杂度之间通常要做一个取舍。

    2. 权限原则

    类似于 RBAC 原则,平台的权限体系采用 OS-RBAC 的概念:

    • OS:O 代表 Organization 组织,S 代表 System 业务系统,即权限是受到组织实体和业务系统双重影响的。
    • RBAC:基于角色的访问控制。
    • OS-RBAC:组织实体-业务系统-用户-角色-权限标识。分为两种情况:一种是有从属组织的个人账户;另一种是无从属组织的个人账户,后者无组织,但同样遵守 RBAC 的权限限定,且其权限标识体系允许组织为空。
    • 资源标识:分为逻辑资源和实体资源。逻辑资源如菜单、页面、表单、按钮组、按钮、字段等功能型资源,或人员档案、考勤记录、任务记录、位置数据、积分、电子钱包等数据资源;实体资源如椅子、凳子、电脑、车辆等实物资产,另外有时候部分逻辑资源也可以归纳为实体资源,如电子照片、视频文件、音乐文件等。
    • 条件标识:权限的约束条件,主要有可见组织架构范围限定、时间限定、区域限定等。例如某权限仅财务部可见,有效期至11月2号,这里『财务部』属于可见组织架构范围限定,『至11月2号』则是时间限定。
    • 权限标识:用于标识账户实体在指定的条件下拥有访问某项功能、查看某些数据的权限。资源标识和条件标识与权限标识关联,权限标识与角色关联,角色与用户关联。例如张三(用户)-研发人员(角色)-拥有『研发部』所有人员档案的增上改查权限。
    • 业务系统标识符:受『业务权限独立原则』的约束,与传统的资源权限有所不同的是,所有权限标识都与具体的业务系统关联,例如企业CRM系统就是一个业务系统,具体的权限标识与业务系统有直接的关系,例如菜单、表单、页面、按钮、图片等资源。
    • 权限策略组:权限策略组是在 OS-RBAC 基础上设置的,为简化权限配置的一种辅助手段,在实际应用中可以不创建策略组。策略组分为平台级策略组和业务系统级别的策略组,两种策略组的作用域仅限于相同组织实体内部,但对于无从属组织的个人账户除外。策略组与角色类似,可以将资源权限绑定到策略组中,但不同之处是,平台级策略组可以横跨业务系统进行平台级的资源权限绑定。因为账户体系跨越多个子系统,在遵循『业务权限独立原则』的限定下,每个子系统都需要做一套权限配置,操作上较为繁琐,因此充分运用策略组可以大大简化权限配置工作。平台可以内置多套常用的策略组,终端用户可以直接选用策略组,也可以基于某个策略组为基础,进行修改。值得注意的是,策略组的作用域仅限于相同组织实体内部,即策略组可以横跨业务系统,但不能同时作用于多个组织实体。
    • 权限交集:与 RBAC2 的静态职责分离-角色互斥原则相反,平台采用多角色权限并集的设计。
    RBAC模型
    RBAC模型

    『权限标识』示例:在企业CRM系统[1]中,在2019年3月5号以前[2],对百度科技[3],研发中心[4],在广东区域[5]的所有人事档案[6]拥有只读权限[7]。

    1. [1]业务系统标识;
    2. [2]条件标识:时间限定;
    3. [3]组织实体标识;
    4. [4]条件标识:可见组织架构范围限定;
    5. [5]条件标识:区域范围限定;
    6. [6]资源标识;
    7. [7]权限类型。

    3. 从属关系梳理

    为简单起见,我们将不遵守『从属关系隔离原则』,即用户实体与组织实体的从属关系与业务系统无关。系统涉及的实体类型有:

    • 业务系统(系统标识)
    • 服务账户(客户端)
    • 个人账户实体
    • 组织账户实体
    • 组织架构
    • 用户组(非必选项)
    • 角色实体
    • 权限实体
    • 资源实体
    • 限定条件实体
    • 权限策略组(非必选项)

    3.1 与组织实体强关联的实体

    基于『组织实体隔离原则』,这类实体类型不能脱离组织实体独立存在。

    • 组织架构
    • 角色实体
    • 权限实体
    • 资源实体
    • 限定条件实体

    由于组织架构不能脱离组织实体单独存在,因此当用户实体绑定组织架构时,该用户实体必须隶属于该组织架构所从属的组织实体。同理可知以下从属关系遵从同样的约束——即每对关系的两个实体对象必须属于相同的组织实体:

    • 用户与角色
    • 角色与权限
    • 资源与权限
    • 限定条件与权限

    3.2 与业务系统强关联的实体

    基于『业务系统隔离原则』,这类实体类型不能脱离业务系统独立存在。

    • 权限实体
    • 资源实体
    • 限定条件实体

    4. 实体类型

    基于以上各项原则,实体类型又分为以下几种情况:

    • 组织实体(未认证):在组织实体的模式下,可以按照组织的管理要求,独立设置一套组织架构、账户和数据权限体系,比如设置下属企业、分公司、部门、岗位职务、角色权限,组织实体缺省分配一个管理员帐户,拥有全部权限,由管理员初始化配置信息。
    • 组织实体(已认证):拥有未认证组织实体的所有权利,但已认证的实体通常拥有更多的配额更少的功能限制,此外有些特定的业务功能和业务流程,必须是实名认证的实体才能使用,比如支付和交易。
    • 个人实体(未认证):在个人实体的模式下,享受的权利由具体的业务系统决定,原则上个人实体作为独立的账户类型,应该享有基本的功能权限和数据权限,如个人中心的各项功能等。
    • 个人实体(已认证):与组织实体(已认证)类似。
    • 个人实体(未从属于组织):未从属组织的个人实体账户,与上述个人实体类型一致。
    • 个人实体(从属单个组织):从属单个组织的个人实体账户,除了具备个人实体账户的原本权利外,还受到组织权限的约束,原本个人实体不享受的权利,可能现在可以享受,原本享受的权利,可能现在不可以享受了。
    • 个人实体(从属多个组织):当个人实体账户从属于多个组织时,除了个人账户原本拥有的权利外,所从属的组织所带来的权利须遵循『组织实体隔离原则』,且受到『从属关系隔离原则』的约束,具体的权利配置由各个业务系统独立管理。这里有两种情况:一是在用户登录时,必须选择所属的组织机构,类似于 LOL 游戏,在登录时须选择所属的区域和服务器;二是在用户登录后,可以自由选择组织实体,类似于阿里云或华为云的区域选择,在用户未选择所属组织时,应当按照未从属于组织的个人实体账户对待。
    • 组织管理员:组织管理员拥有该组织内部的全部资源权限,例如可以创建个人账户,在个人未完成首次登录前,可以删除(解雇),修改,在个人完成登录后,则权限移交给了个人;删除(解雇)时,只是个人脱离组织,个人不再拥有组织员工的权限,在组织内的个人工作经历仍然保留,组织清除离职员工,则这些在职经历将不为企业可管理,但个人自己可见,不可变更。

    5. 用户分类
     

    用户分类
    用户分类

     

    6. 组织分类

    组织分类
    组织分类

    三、基础信息模块

    基础信息,主要针对个人实体和组织实体,如企业工商信息、通用信息等要满足灵活扩展的需求,实体的类型种类繁多,随着业务场景的变化,信息结构的变化也可能比较频繁。在技术上建议采用以下两种方式应对:

    1. EAV 数据模型

    EAV 即 Entity(实体)-Attribute(属性)-Value(值)数据模型,将传统的 ORM 映射模型——即实体属性与数据库表字段一一对应的模型,变换为实体属性与数据表的行记录一一对应的模型。EAV 模型大大增加了数据映射和相关业务逻辑的复杂程度,但是具备高度的灵活性,能够满足随时变化的信息结构,满足动态变更的实体结构、满足字段级权限控制、满足字段级数据版本历史等功能。

    2. 采用松散型数据结构的数据库方案

    其中的代表便是 MongoDB:一个介于关系数据库和非关系数据库之间的分布式文件存储数据库产品,在 CAP 理论中属于 CP 范畴,支持松散数据结构,支持复杂的混合数据类型,支持 JSON 和文档存储。采用此方案的优势比较明显,除了能够满足 EAV 模型所具备的大部分功能外,还大大简化了技术复杂度,支持分布式部署,推荐采用此方案。

    3. 信息分类

    平台的信息主要分为基础信息和业务信息两大类。基础信息分为个人实体信息和组织实体信息,主要描述实体的基本信息、通用信息,与业务相关性不大,例如姓名、性别、身份证号码、手机号码、企业通用信息、企业工商信息等。业务信息由各业务系统自行管理和维护,UIMS 不涉及。

    实体类别信息类别信息范围备注
    个人信息基础信息昵称、性别默认公开
    个人信息基础信息身份证信息、籍贯、性别、出生日期、学历、工作履历、电话号码、通信地址、照片、银行卡号须用户授权收集和公开
    个人信息业务信息LBS数据须用户授权收集和公开
    个人信息业务信息用户移动终端的设备信息,包括IP地址、Mac地址、操作系统信息、设备型号、识别码等须用户授权收集和公开
    个人信息业务信息用户的行为信息,包括操作记录,cookies,通过平台编辑或传送的文字、图片、语音或视频信息等须用户授权收集和公开
    个人信息业务信息用户喜好、特长、手工标签、自动标签、社交互动信息等须用户授权收集和公开
    组织信息基础信息组织工商信息:名称、法人、营业范围、注册日期、注册资本、通信地址、工商注册号、公司类型、纳税人识别号默认公开,自动审核
    组织信息基础信息组织介绍、品牌介绍、微信公众号、企业官网、对外联络电话、客服电话默认公开,须人工审核
    组织信息基础信息企业资质、股权结构、对外投资、工商登记变更记录、企业年报、公司发展历程、行政许可须组织授权收集和公开
    组织信息基础信息核心团队和成员、融资历程、核心产品、公司规模、知识产权须组织授权收集和公开
    组织信息基础信息组织架构、组织成员档案、司法风险、法律诉讼须组织授权收集和公开

    所有与信息收集、储存、处理及数据安全有关的书面政策,应当出具《隐私政策》并进行声明。部分组织信息由于可在网上公开查到,且是法定必须公布的信息,因此可以默认公开。

    四、其他功能

    一)软件授权

    基于两级账户体系,建立云平台付费授权机制,针对用户账户和组织账户进行独立授权。根据产品的商业策略,可执行灵活的付费模式:

    • 时效限制:年付、季付、月付,不同时效费用不同。
    • 功能限制:授权不同的功能,费用不同。
    • 数量限制:最大组织数量限制、最大用户数量限制,不同的数量费用不同。

    二)组织入驻

    UIMS 应提供一个组织实体注册登记的流程,允许组织主动提交基本信息,开户入驻平台。此外,应提供在管理后台手工录入组织开户的功能。

    三)实名认证

    分为个人账户实名认证和组织账户实名认证,尽量通过技术手段自动执行实名认证的审核过程,减少甚至取消人工干预。UIMS 应提供实名认证的功能和流程。

    四)资质审核

    资质审核分为两部分:一是部分实体实名认证过程中的人工核查;二是对实体提交的额外资质进行技术或人工审核。

    五)组织绑定

    基于『从属关系隔离原则』,个人账户应在具体的业务系统中绑定组织账户,绑定过程分为两种类型:一是由组织管理员手工创建的从属个人账户,另一个是个人账户申请加入某个组织。业务系统应该提供此功能和流程。例如,个人注册帐号后,可主动登记绑定组织,对已注册登记的组织则要该组织管理员审核,未在系统中注册登记的组织,则始终处于待审核状态。

    六)组织解绑

    允许个人账户解除与组织之间的从属关系。解绑分为两种情况:一是个人账户主动解除关系,二是组织管理员解绑、解雇或清除雇员(个人账户)。其中第一种个人解绑的,应当由组织进行审核批准,个人申请解除绑定关系,组织进行审核,但是是否需要审核,应交由具体的业务系统自行决定。

    七)间接雇佣(从属)关系

    雇佣(从属)关系分为直接雇佣与间接雇佣关系。例如保安员在某保安公司入职(直接雇佣),在某物业作保安(间接雇佣)。考虑两种办法标识间接雇佣关系:

    • 增加服务单位(项目点、物业社区)的实体概念
    • 利用组织内部的组织机构体系,将间接雇佣单位作为当前组织的分支机构进行处理。

    八)账户注销

    分为个人账户的注销和组织账户的注销。UIMS 应提供相应的页面完成账户注销的操作。

    九)私有化部署

    原则上拒绝私有化部署,但对于特定的客户,考虑私有化部署。私有化部署须考虑版本升级问题,在软件架构设计时,尽量遵循业务系统和技术系统分离的原则,并抽离公共模块,最大限度为私有部署的版本提供升级服务。

    五、总结

    总体来说,统一身份管理系统要做的事情有这么几件:

    • 定义实体
    1. 业务系统实体
    2. 服务账户实体(客户端)
    3. 组织实体
    4. 组织架构
    5. 个人实体
    6. 角色实体
    7. 权限标识
    8. 资源标识
    9. 条件标识
    • 处理上述各实体之间的关系,并提供数据结构
    • 提供鉴权 APIs 和业务 APIs
    • 提供其他功能:统一注册功能(页面和流程)、统一登录功能、软件授权
      、组织入驻、组织绑定/解绑、资质审查。

    转自:https://www.jianshu.com/p/990d8acfdb69

    参考:http://www.ruanaaly.com

    展开全文
  • ASP.NET通用权限管理系统源代码(含文档、数据库)

    千次下载 热门讨论 2013-08-27 11:30:49
    ASP.NET通用权限管理系统源代码(含文档、数据库) 1.菜单导航管理 2.操作按钮 3.角色管理 4.部门管理 5.用户管理(用户权限) 6.用户组管理(设置成员,用户组权限) 7.系统配置(动态配置系统参数) 8.附加属性...
  • DRF 权限管理 AllowAny : 默认的权限,允许任何用户进行操作 IsAuthenticated :只允许 授权的 用户 进行操作 IsAdminUser : 只允许 后台管理员进行操作 ...DRF 授权管理 DRF 默认采用的是 session 登...

    DRF 权限管理

    • AllowAny : 默认的权限,允许任何用户进行操作
    • IsAuthenticated :只允许 授权的 用户 进行操作
    • IsAdminUser : 只允许 后台管理员进行操作
    • IsAuthenticatedOrReadOnly 只允许授权的用户所有进行操作,没有授权人的都可以进行读取

    局部设置权限

    全局设置权限

    DRF 授权管理

    DRF 默认采用的是 session 登录 授权 (一般不用)

    • drf配置 登录 入口

    JWT (JSON WEB TOKEN)授权管理

    • 引入 djangorestframework-simplejwt
      pip install djangorestframework_simplejwt

    具体配置参考 :SimpleJWT

    展开全文
  • Spring Boot设计目的是用来简化Spring应用的初始搭建以及开发过程,而Shiro是一个强大且易用的Java权限框架,有身份验证、授权、加密和会话管理等功能。本课程重点讲解如何使用Spring Boot与Shiro进行无缝整合,实现...
  • 其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为...
  • 权限管理系统 一个可以管理用户权限的前一级分离系统 在线演示 测试账号 管理员:admin 123456普通用户:user1 123456这些数据是存在数据库里的,注册一个用户,然后在数据库里把角色替换1(管理员角色)即可 开发...
  • C#完整版权限管理系统

    热门讨论 2015-06-09 09:35:45
    C#,Jquery,EASYUI写得通用的权限管理系统,也是一个很漂亮,很实用的web应用程序框架!
  • 权限管理

    千次阅读 2017-12-29 20:24:07
    关于权限菜单的设计 ...权限设计(初稿)  ... 权限管理往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断“Who对What(Which)进行How的操作”的逻辑表达式是否为真。针对不同的应用,需要
  • 这就极大地简化了权限管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以 很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新...
  • 基本上涉及到用户参与的系统都要进行权限管理权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。权限管理包括用户身份认证...
  • svn用户权限管理

    热门讨论 2011-10-01 15:16:41
    svn用户权限管理,限定不同用户之间的不同权限,项目经理可以查看项目的所有信息,开发人员只能查看开发人员的信息等等。
  • 大家好,权限管理可以说是每个系统都必备的一个功能,也有可能是一个权限系统管理同一个企业多个系统的用户权限。所以作者今天和大家分享一个权限管理系统的高保真原型的制作方法,这个原型包括了角色管理、用户管理...
  • RBAC权限管理模(转载)

    千次阅读 2019-01-01 14:18:19
    我们在做任何一款产品的时候,或多或少都会涉及到用户和权限的问题。譬如,做企业类软件,不同部门、不同职位的人的...但在设计产品的用户和权限的关系的时候,很多产品经理可能按照感觉来,在并不清楚用户和权限是...
  • 权限之间的衍生关系简化了授权管理,同时也增加了权限判决的难度,准确、高效地计算权限衍生对授权和访问控制具有重要意义。在给出基于资源和操作层次的权限衍生规则基础上,针对授权管理权限查询较频繁而权限更新...
  • Windows 权限管理

    千次阅读 2017-09-14 11:03:08
    Windows 权限管理基础概念管理员用户是被授予高特权(安全令牌)的账户。 标准用户是被授予标准权限(筛选令牌)的账户。用户与权限在windows vista之前,用户登录,就会创建一个安全令牌(security token),当代码...
  • C#权限管理系统源代码

    热门讨论 2014-08-28 18:00:41
    分享下吧,好不容易搞到的权限管理及框架系统源代码,没有任何封装,很值得借鉴,vs2010+sql2005
  • Vue:细粒度动态权限管理解决方案

    千次阅读 2018-04-22 12:13:32
    权限管理是每个后台管理系统都需要面对的问题。细粒度动态权限管理更是一个不太好啃但是必须解决的硬需求。本文记录了一种基于角色的动态权限管理方法,实现方法不是很优雅,如果以后发现了更优雅的方法再来更新。该...
  • SpringSecurity授权管理介绍

    千次阅读 2019-12-05 17:07:11
      权限管理的两大核心是:认证和授权,前面我们已经介绍完了认证的内容,本文就给大家来介绍下SpringSecurity的授权管理 一、注解操作   我们在控制器或者service中实现授权操作比较理想的方式就是通过相应的...
  • 基于layui的通用后台权限管理系统

    千次阅读 2020-12-10 17:46:34
    基于layui的通用后台权限管理系统 基于layui的通用后台权限管理系统 Demo 链接地址: http://liu168.xyz/Admin/Login.aspx. 账号密码:admin admin (密码admin与admin账号下密码同用,防止别人修改admin密码后,...
  • Hive之——权限管理(授权)

    万次阅读 2018-11-18 17:26:02
     HIVE授权管理,类似于操作系统权限可以授予给不同的主题,如用户(USER),组(GROUP),角色(ROLES),Hive还是支持相当多的权限管理功能,满足一般数据仓库的使用,同时HIVE能支持自定义权限。  HIVE授权并不是完全...
  • JQuery UI实现权限管理系统

    热门讨论 2012-03-20 14:46:54
    很好的学习资料,有助于对其JQqery UI框架的运用和掌握,权限管理使你理解的很透彻,值得下载
  • 不论是在技术层面还是在产品层面,大数据平台环境下的权限管理工作都是一个让人伤脑筋的烫手山芋,它不仅仅是一个技术问题,还是一个业务问题,甚至还可能是一个人际沟通和权衡利益得失的哲学问题。。。所以,以下...
  • 吉日嘎拉福利大派送,通用权限管理大师之作。 通用权限管理系统组件(GPM - General Permissions Manager)自2003年开始发布,目前是国内注册用户和免费盗版用户最多的权限管理系统,是各种信息管理系统开发中彻底的...
  • 一款通用的后台模块管理系统,角色管理系统,角色授权系统,文件为axure 源文件,使用者可以在上面进行修改,适用自己的业务逻辑
  • Kinguser授权管理包.zip

    2013-08-22 12:46:47
    “Kinguser授权管理”是由Kingroot团队开发的一款安卓手机权限管理软件,具有root权限授权、软件权限管理两大功能。 与Superuser相比,“Kinguser授权管理”具备以下6大特色,更适合Android开发者及普通用户使用: 1...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,405,884
精华内容 562,353
关键字:

权限管理