Shiro(2)---授权

Shiro授权

1.授权流程

这里写图片描述

2.授权方式

Shiro 支持三种方式的授权:

1.编程式:通过写if/else 授权代码块完成:

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}

2.注解式:通过在执行的Java方法上放置相应的注解完成:

@RequiresRoles("admin")
public void hello() {
//有权限的操作
}

3.JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:####  

<shiro:hasRole name="admin">
<!— 有权限—>
</shiro:hasRole>

3.入门测试程序

测试分为基于角色的权限控制和基于资源的权限控制(开发中建议使用)

1. 创建shiro-permission.ini文件模拟数据源

#用户
[users]
#用户zhang的密码是123,此用户具有role1和role2两个角色
zhang=123,role1,role2
wang=123,role2

#权限
[roles]
#角色role1对资源user拥有createupdate权限
role1=user:create,user:update
#角色role2对资源user拥有createdelete权限
role2=user:create,user:delete
#角色role3对资源user拥有create权限
role3=user:create

权限标识符号规则:资源:操作:实例(中间使用半角:分隔)
user:create:01 表示对用户资源的01实例进行create操作。
user:create 表示对用户资源进行create操作,相当于user:create:*,对所有用户资源实例进行create操作。
user:*:01 表示对用户资源实例01进行所有操作。

2. 测试代码

public void testPermission(){
        //根据ini文件创建SecurityManagerFactory
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
        SecurityManager securityManager = factory.getInstance();
        //将securityManager设置到运行环境中
        SecurityUtils.setSecurityManager(securityManager);
        //创建主体对象
        Subject subject = SecurityUtils.getSubject();
        //有身份和凭证信息生成一个token
        UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }
        boolean isAuthenticated = subject.isAuthenticated();
        System.out.println("用户认证状态: "+isAuthenticated);
        //基于角色的权限控制
        boolean isHasRole1 = subject.hasRole("role1");
        System.out.println("是否有role1角色: "+isHasRole1);
        boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1","role2","role3"));
        System.out.println("是否有所有角色: "+hasAllRoles);
        //使用check进行授权,如果授权失败则抛异常
        subject.checkRole("role1");
        subject.checkRoles("role1","role2");
        //基于资源的权限控制
        boolean isPermitted = subject.isPermitted("user:create");
        System.out.println("是否拥有该权限: "+isPermitted);
        boolean isPermittedAll = subject.isPermittedAll("user:create:1","user:delete");
        System.out.println("是否拥有所有的权限: "+isPermittedAll);
        //使用check进行授权,如果授权失败则抛异常
        subject.checkPermission("user:create");
        subject.checkPermissions("user:create","user:delete");
    }

4.自定义realm

这里用到的是基于资源的权限控制
1.在自定义realm完善doGetAuthorizationInfo()方法

// 授权
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        //获取身份信息
        String principal = (String)principals.getPrimaryPrincipal();
        //根据身份信息从数据库中获取权限数据
        //使用静态数据进行模拟...
        List<String> permissions = new ArrayList<String>();
        permissions.add("user:create");
        permissions.add("user:delete");
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //将权限数据封装到SimpleAuthorizationInfo对象中
simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

2.ini配置文件还使用认证阶段使用的,不用改变。

[main]
#自定义realm
customRealm=com.ak.shiro.CustomRealm
#将realm设置到securityManager
securityManager.realms=$customRealm

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串有权限,否则 没有权限,抛出异常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章