Apache Shiro进行权限认证

权限认证核心要素

权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源。在权限认证中,最核心的三个要素是:权限,角色和用户:

权限(permission):即操作资源的权利,如访问某个url,对某个模块数据进行增删改查
角色(role):权限的集合,一种角色可以包含多种权限。例如操作员角色可查看系统账单、进行结账操作多种权限。
用户(user):也就是身份认证中提到的subject一角。

授权

授权有三种方式

  1. 编程式授权:在代码中进行授权操作,可基于角色和权限两种方式。
  2. 注解式授权:使用注解对方法或类进行授权,标注该类可被哪些权限、角色所使用。
  3. Jsp标签授权:shiro比较灵活的地方笔者觉得就是jsp标签授权,通过shiro的guest、user、principal等标签,可通过访问权限的不同,控制页面信息显示。免去了一大部分后台处理逻辑。

编程式授权实例

  1. 同样首先创建ini文件
[users]  
test1=123456,role1,role2  
test1=123,role1

test1的用户,密码为123456。有两个角色role1,role2
test2的用户,密码为123。有一个角色role1
2. java代码通过hasRole 和checkRole的方法可判断某用户是否具有role1、role2角色权利
创建ShiroUtil

package com.shiro.bean;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class ShiroUtil {
    public static Subject login(String userName,String password){
        // 读取配置文件,初始化SecurityManager工厂
        Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini");
        // 获取securityManager实例
        SecurityManager securityManager=factory.getInstance();
        // 把securityManager实例绑定到SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);
        // 得到当前执行的用户
        Subject currentUser=SecurityUtils.getSubject();
        // 创建token令牌,用户名/密码
        UsernamePasswordToken token=new UsernamePasswordToken(userName, password);
        try{
            // 身份认证
            currentUser.login(token);   
            System.out.println("身份认证成功!");
        }catch(AuthenticationException e){
            e.printStackTrace();
            System.out.println("身份认证失败!");
        }
        return currentUser;
    }
}

新建roleTest类,通过调用user的hasRole、checkRole方法判断用户权限。
当用户拥有指定角色时,返回true
断言用户是否拥有指定角色
Shiro还支持以断言的方式进行授权验证。断言成功,不返回任何值,程序继续执行;断言失败时,将抛出异常信息。使用断言,可以使我们的代码更加简洁。

public class RoleTest {  

    @Test  
    public void testHasRole() {  
        Subject currentUser=ShiroUtil.login("test1", "123456");  
        // Subject currentUser=ShiroUtil.login("test2", "123");  
        System.out.println(currentUser.hasRole("role1")?"有role1这个角色":"没有role1这个角色");  
        boolean []results=currentUser.hasRoles(Arrays.asList("role1","role2","role3"));  
        System.out.println(results[0]?"有role1这个角色":"没有role1这个角色");  
        System.out.println(results[1]?"有role2这个角色":"没有role2这个角色");  
        System.out.println(results[2]?"有role3这个角色":"没有role3这个角色");  
        System.out.println(currentUser.hasAllRoles(Arrays.asList("role1","role2"))?"role1,role2这两个角色都有":"role1,role2这个两个角色不全有");  

        currentUser.logout();  
    }  

    @Test  
    public void testCheckRole() {  
        Subject currentUser=ShiroUtil.login("test1", "123456");  
        // Subject currentUser=ShiroUtil.login("test2", "123");  
        currentUser.checkRole("role1");  
        currentUser.checkRoles(Arrays.asList("role1","role2"));  
        currentUser.checkRoles("role1","role2","role3");  

        currentUser.logout();  
    }  
}  

通过权限permission的权限验证方式如下:

[users]
test1=123456,role1,role2
test1=123,role1
[roles]
role1=user:select
role2=user:add,user:update,user:delete

这里补充了role1、role2用户具体具有哪些操作权,role1可进行select操作,同理,role2可进行增删改操作。同样调用user关于permission认证的方法,可对用户具体操作权限进行认证。
测试代码:


public class PermissionTest {

    @Test
    public void testIsPermitted() {
        Subject currentUser=ShiroUtil.login("test01", "123456");
        // Subject currentUser=ShiroUtil.login("test02", "123");
        System.out.println(currentUser.isPermitted("user:select")?"user:select这个权限":"没有user:select这个权限");
        System.out.println(currentUser.isPermitted("user:update")?"user:update这个权限":"没有user:update这个权限");
        boolean results[]=currentUser.isPermitted("user:select","user:update","user:delete");
        System.out.println(results[0]?"user:select这个权限":"没有user:select这个权限");
        System.out.println(results[1]?"user:update这个权限":"没有user:update这个权限");
        System.out.println(results[2]?"user:delete这个权限":"没有user:delete这个权限");
        System.out.println(currentUser.isPermittedAll("user:select","user:update")?"user:select,update这两个权限":"user:select,update这两个权限不全有");

        currentUser.logout();
    }

    @Test
    public void testCheckPermitted() {
        Subject currentUser=ShiroUtil.login("test01", "123456");
        // Subject currentUser=ShiroUtil.login("test02", "123");
        currentUser.checkPermission("user:select");
        currentUser.checkPermissions("user:select","user:update","user:delete");
        currentUser.logout();
    }
}

猜你喜欢

转载自blog.csdn.net/dingming001/article/details/79451223