程序员每天写500字每天写1000字

shiro权限管理自定义realm授权测试精讲篇

2019-06-16  本文已影响3人  您好简书

上边的程序通过shiro-permission.ini对权限信息进行静态配置,实际开发中从数据库中获取权限数据。就需要自定义realm,由realm从数据库查询权限数据。
realm根据用户身份查询权限数据,将权限数据返回给authorizer(授权器)。

shiro-permission.ini

#\u7528\u6237
[users]
#\u7528\u6237zhang\u7684\u5bc6\u7801\u662f123\uff0c\u6b64\u7528\u6237\u5177\u6709role1\u548crole2\u4e24\u4e2a\u89d2\u8272
zhangsan=123,role1,role2
wang=123,role2

#\u6743\u9650
[roles]
#\u89d2\u8272role1\u5bf9\u8d44\u6e90user\u62e5\u6709create\u3001update\u6743\u9650
role1=user:create,user:update
#\u89d2\u8272role2\u5bf9\u8d44\u6e90user\u62e5\u6709create\u3001delete\u6743\u9650
role2=user:create,user:delete
#\u89d2\u8272role3\u5bf9\u8d44\u6e90user\u62e5\u6709create\u6743\u9650
role3=user:create

// 授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        // 获取身份信息
        String username = (String) principals.getPrimaryPrincipal();
        // 根据身份信息从数据库中查询权限数据
        //....这里使用静态数据模拟
        List<String> permissions = new ArrayList<String>();
        permissions.add("user:create");
        permissions.add("user.delete");
        
        //将权限信息封闭为AuthorizationInfo
        
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for(String permission:permissions){
            simpleAuthorizationInfo.addStringPermission(permission);
        }
        
        return simpleAuthorizationInfo;
    }

测试:
AuthorizationTest.java


package cn.itcast.shiro.authorization;

import java.util.Arrays;

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.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;

/**
 * 
 * <p>
 * Title: AuthorizationTest
 * </p>
 * <p>
 * Description: 授权测试
 * </p>
 * <p>
 * Company: www.itcast.com
 * </p>
 * 
 * @author 传智.燕青
 * @date 2015-3-25上午9:40:52
 * @version 1.0
 */
public class AuthorizationTest {

    // 角色授权、资源授权测试
    @Test
    public void testAuthorization() {

        // 创建SecurityManager工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory(
                "classpath:shiro-permission.ini");

        // 创建SecurityManager
        SecurityManager securityManager = factory.getInstance();

        // 将SecurityManager设置到系统运行环境,和spring后将SecurityManager配置spring容器中,一般单例管理
        SecurityUtils.setSecurityManager(securityManager);

        // 创建subject
        Subject subject = SecurityUtils.getSubject();

        // 创建token令牌
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
                "123");

        // 执行认证
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("认证状态:" + subject.isAuthenticated());
        // 认证通过后执行授权

        // 基于角色的授权
        // hasRole传入角色标识
        boolean ishasRole = subject.hasRole("role1");
        System.out.println("单个角色判断" + ishasRole);
        // hasAllRoles是否拥有多个角色
        boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1",
                "role2"));
        System.out.println("多个角色判断" + hasAllRoles);

        // 使用check方法进行授权,如果授权不通过会抛出异常
        // subject.checkRole("role13");

        // 基于资源的授权
        // isPermitted传入权限标识符
        boolean isPermitted = subject.isPermitted("user:create:1");
        System.out.println("单个权限判断" + isPermitted); 

        boolean isPermittedAll = subject.isPermittedAll("user:create:1",
                "user:delete");
        System.out.println("多个权限判断" + isPermittedAll);

        // 使用check方法进行授权,如果授权不通过会抛出异常
        subject.checkPermission("items:create:1");

    }

    // 自定义realm进行资源授权测试
    @Test
    public void testAuthorizationCustomRealm() {

        // 创建SecurityManager工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory(
                "classpath:shiro-realm.ini");

        // 创建SecurityManager
        SecurityManager securityManager = factory.getInstance();

        // 将SecurityManager设置到系统运行环境,和spring后将SecurityManager配置spring容器中,一般单例管理
        SecurityUtils.setSecurityManager(securityManager);

        // 创建subject
        Subject subject = SecurityUtils.getSubject();

        // 创建token令牌
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
                "111111");

        // 执行认证
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("认证状态:" + subject.isAuthenticated());
        // 认证通过后执行授权

        // 基于资源的授权,调用isPermitted方法会调用CustomRealm从数据库查询正确权限数据
        // isPermitted传入权限标识符,判断user:create:1是否在CustomRealm查询到权限数据之内
        boolean isPermitted = subject.isPermitted("user:create:1");
        System.out.println("单个权限判断" + isPermitted);

        boolean isPermittedAll = subject.isPermittedAll("user:create:1",
                "user:create");
        System.out.println("多个权限判断" + isPermittedAll);

        // 使用check方法进行授权,如果授权不通过会抛出异常
        subject.checkPermission("items:add:1");

    }

}

授权流程

4.5 授权流程

1、对subject进行授权,调用方法isPermitted("permission串")
2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
3、ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据
调用realm的授权方法:doGetAuthorizationInfo

4、realm从数据库查询权限数据,返回ModularRealmAuthorizer
5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对
6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。

上一篇 下一篇

猜你喜欢

热点阅读