框架学习--shiro权限管理框架基础

1.权限管理

权限管理实现用户对系统资源访问的控制,主要包括两个部分,认证和授权。认证部分即登陆,有资格进入系统。授权即进入系统之后,只有你被授权的资源你才有资格访问。举个例子,教务管理系统,老师的账号登陆之后,可以查看所有同学的成绩,并进行修改。但是学生的账号登陆之后,只能看到自己的成绩,并不能进行修改等操作,因为没有被授权。

2.权限模型

权限信息肯定是放在数据库之中进行管理的,那我们就得知道什么样得权限模型是好得。

主体(账号、密码)

资源(资源名称、访问地址)

权限(权限名称、资源id

角色(角色名称)

角色和权限关系(角色id、权限id

主体和角色关系(主体id、角色id

注:一般资源和权限是放在同一张表里面得,什么样得权限能访问什么资源(一般也就是请求的url)

3.授权流程

授权是shiro最主要的功能,在理解授权之前,我们先要搞清楚几个概念

1.SecurityManager  

SecurityManager即安全管理器,对全部的subject进行安全管理(也就是任何在applicationcontext-shiro中配置的bean,都要通过它的认证),它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等

<!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="customRealm" />
		<!-- 注入缓存管理器 -->
 		<property name="cacheManager" ref="cacheManager"/> 
		<!-- 注入session管理器 -->
	   	<property name="sessionManager" ref="sessionManager" /> 
		<!-- 记住我 -->
<!-- 		<property name="rememberMeManager" ref="rememberMeManager"/> -->
		
	</bean>

2.realm

Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。

更确切的说是从数据库中取出信息和从登陆会话中取出的信息进行认证和授权。

3.authenticator和authorizer

前者是认证器,对用户身份进行认证

后者是授权器,判断用户是否有对此功能的操作权限。

4.subject

Subject即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体

,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,

外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权

理解了之后接下来就是授权流程:

1、对subject进行授权,调用方法isPermitted("permission串")

2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权

3、ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据

调用realm的授权方法:doGetAuthorizationInfo

 

4、realm从数据库查询权限数据,返回ModularRealmAuthorizer

5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对

6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,

否则 没有权限,抛出异常。


	// 用于认证,
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {

		// token是用户输入的
		// 第一步从token中取出身份信息
		String userCode = (String) token.getPrincipal();

		// 第二步:根据用户输入的userCode从数据库查询
		SysUser sysUser=null;
		
		try {
            sysUser=sysService.findSysUserByUserCode(userCode);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
		
		// 
	

		// 如果查询不到返回null
		//数据库中用户账号是zhangsansan
		if(sysUser==null){//
			return null;      
		}
		//盐
		String salt=sysUser.getSalt();
		
		// 模拟从数据库查询到密码
		String password = sysUser.getPassword();
		

		// 如果查询到返回认证信息AuthenticationInfo
		ActiveUser activeUser=new ActiveUser();
		
		activeUser.setUserid(sysUser.getId());
		activeUser.setUsercode(sysUser.getUsercode());
		activeUser.setUsername(sysUser.getUsername());
		//..
		//根据用户id取出菜单
		
		//通过sevice取出菜单
		List<SysPermission> menus=null;
		try {
		    menus=sysService.findMenuListByUserId(sysUser.getId());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
		//将用户菜单设置到activeuser
		activeUser.setMenus(menus);
		//将activeuser设置到SimpleAuthenticationInfo
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
		        activeUser, password,ByteSource.Util.bytes(salt), this.getName());

		return simpleAuthenticationInfo;
	}

	// 用于授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// TODO Auto-generated method stub
	    //从principals获取主身份信息
	    //将getprimaryprinciple方法返回值转换为真实的身份类型
	    ActiveUser activeUser=(ActiveUser)principals.getPrimaryPrincipal();
	    List<SysPermission> permissionList=null;
	    //根据身份信息获取权限信息
	    //连接数据库...
	    //模拟从数据库获取到数据
	    try {
            permissionList=sysService.findPermissionListByUserId(activeUser.getUserid());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
	    //单独定义一个集合对象
	    List<String> permissions=new ArrayList<String>();
	    if(permissionList!=null){
	        for(SysPermission sysPermission:permissionList)
	        {
	            //将数据库中的权限标识符号放入集合
	            permissions.add(sysPermission.getPercode());
	        } 
	    }
	   

	    
        //查到权限数据,返回授权信息(要包括 上边的permissions)
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //将上边查询到授权信息填充到simpleAuthorizationInfo对象中
        simpleAuthorizationInfo.addStringPermissions(permissions);
	    
		return simpleAuthorizationInfo;
	}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值