shiro授权过程

一、授权的核心概念

授权,也就是权限认证或访问控制,即在应用中控制谁能访问哪些资源
授权中的核心要素:
1 用户,在shiro中代表访问系统的任何客户端,即subject
2 角色,是权限的集合,或字符串值表示的一种能力。
3 权限,即操作资源的权利。比如访问某个页面,以及对某功能模块的添加、修改、删除、查看的权利
(http://shiro.apache.org/authorization.html)

二、授权方式

1、编程式授权

基于角色(role)的编程式授权、基于权限(permission)的编程式授权

1.1 基于角色(role)的编程式授权

public class RoleTest {
    @Test
    public void testHasRole() {
        Subject currentUser=ShiroUtil.login("classpath:shiro_role.ini", "zhangsan", "zs123456");
        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("classpath:shiro_role.ini", "zhangsan","zs123456");
      
        currentUser.checkRole("role1");
        currentUser.checkRoles(Arrays.asList("role1","role2"));
        currentUser.checkRoles("role1","role2","role3");
         
        currentUser.logout();
    }
}

hasRole()和checkRole()的区别在于,前者是有相应角色则返回布尔值,后者是没有角色则会抛出异常。

1.2 基于权限(permission)的编程式授权

public class PermissionTest {
 
    @Test
    public void testIsPermitted() {
        Subject currentUser=ShiroUtil.login("classpath:shiro_permission.ini", "zhangsan", "zs123456");
          
        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("classpath:shiro_permission.ini", "zhangsan", "zs123456");
        currentUser.checkPermission("user:select");
     currentUser.checkPermissions("user:select","user:update","user:delete");
        currentUser.logout();
    }
}

isPermmitted()和checkPermitted()的区别在于:前者是若用户没有相应权限则返回布尔值false,而后者则会抛出异常。

2、注解授权

@RequiresAuthentication 要求subjejct已经通过了身份认证
@RequiresGuest 要求当前subject是一个"guest",即subject必须是没有被记住且没有通过身份认证
@RequiresUser 要求当前subject是一个用户,可以是被记住(rememberMe)的,或者是通过了身份认证的
@RequiresRoles 要求当前subject必须拥有相应角色,value可为一个String集合,默认是And关系。可以标记在类和方法上。
@RequiresPermissions 要求当前subject必须拥有相应权限,value可为一个String集合,默认是And关系。可以标记在类和方法上。

@RequiresRoles注解:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRoles {
 
    /**
     * A single String role name or multiple comma-delimitted role names required in order for the method
     * invocation to be allowed.
     */
    String[] value();
     
    /**
     * The logical operation for the permission check in case multiple roles are specified. AND is the default
     * @since 1.1.0
     */
    Logical logical() default Logical.AND;
}

@RequiresPermission注解:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissions {
 
    /**
     * The permission string which will be passed to {@link org.apache.shiro.subject.Subject#isPermitted(String)}
     * to determine if the user is allowed to invoke the code protected by this annotation.
     */
    String[] value();
     
    /**
     * The logical operation for the permission checks in case multiple roles are specified. AND is the default
     * @since 1.1.0
     */
    Logical logical() default Logical.AND;
 
}

3、jsp标签授权

3.1 在pom.xml中引入shiro-web.jar

3.2 在jsp页面中引入shiro的自定义标签库

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

3.3 在jsp页面中使用shiro:xxx的标签

<shiro:guest>用户没有被RememberMe,也没有通过身份认证时显示  </shiro:guest><shiro:user> 用户被RememberMe,或者通过了身份认证时显示</shiro:user><shiro:authenticated>用户通过了身份认证时显示 </shiro:authenticated>
<shiro:notAuthenticated>用户没有通过身份认证时显示 </shiro:notAuthenticated><shiro:hasRole>用户拥有相应角色则显示  </shiro:hasRole>
<shiro:lacksRole> 用户缺少相应角色则显示 </shiro:lacksRole>
<shiro:hasAnyRole>用户拥有其中任意一个角色则显示  </shiro:hasAnyRole><shiro:hasPermission> 用户拥有相应权限则显示</shiro:hasPermission>
<shiro:lacksPermission>用户缺少相应权限则显示 </shiro:lacksPermission>

三、授权过程

图片1

Step 1: Application or framework code invokes any of the Subject hasRole*, checkRole*, isPermitted*, or checkPermission* method variants, passing in whatever permission or role representation is required.

Step 2: The Subject instance, typically a DelegatingSubject (or a subclass) delegates to the application’s SecurityManager by calling the securityManager’s nearly identical respective hasRole*, checkRole*, isPermitted*, or checkPermission* method variants (the securityManager implements the org.apache.shiro.authz.Authorizer interface, which defines all Subject-specific authorization methods).

Step 3: The SecurityManager, being a basic ‘umbrella’ component, relays/delegates to its internal org.apache.shiro.authz.Authorizer instance by calling the authorizer’s respective hasRole*, checkRole*, isPermitted*, or checkPermission* method. The authorizer instance is by default a ModularRealmAuthorizer instance, which supports coordinating one or more Realm instances during any authorization operation.

Step 4: Each configured Realm is checked to see if it implements the same Authorizer interface. If so, the Realm’s own respective hasRole*, checkRole*, isPermitted*, or checkPermission* method is called.

四、权限粒度

资源级别
单个权限:query
单个资源多个权限: user:query user:add 多值user:query,add
单个资源所有权限: user:query,user:add,user:update,user:delete 所有user:*
所有资源的某个权限: *:view

实例级别
单个实例的单个权限 printer:query:lp7200 printer:print:epsoncolor
所有实例的单个权限 printer:print:*
所有实例的所有权限 printer::
单个实例的所有权限 printer:*:lp7200
单个实例的多个权限 printer:query,print:lp7200

printer 等价于 printer::
printer:print 等价与 printer:print:*

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值