0%

shiro-权限

权限管理

shiro-权限

控制谁能访问哪些资源。

谁:主体(Subject)、角色(Role)

哪些资源:资源(Resource)、权限(Permission)

授权方式

  1. 编程

    1
    2
    3
    4
    5
    6
    Subject subject = SecurityUtils.getSubject();
    if(subject.hasRole(“admin”)) {
    //有权限
    } else {
    //无权限
    }
  2. 注解

    1
    2
    3
    4
    @RequiresRoles("admin")
    public void hello() {
    //有权限
    }
  3. 标签

    JSP/GSP 标签

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

基于角色的访问控制(隐式角色)

  1. 配置shiro-role.ini

    resource下新建shiro-role.ini

    1
    2
    3
    [users]
    zhang=123,role1,role2
    wang=123,role1
  2. Base

    封装了开头和结尾的方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    package com.xiaoruiit.shiro.config;

    import org.apache.shiro.SecurityUtils;
    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.apache.shiro.util.ThreadContext;
    import org.junit.After;

    /**
    * @author hxr
    * @Classname BaseAuthorizationTest
    * @Description Authorization base
    */
    public class BaseAuthorizationTest {

    protected void login(String configFile, String username, String password) {
    //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
    Factory<SecurityManager> factory =
    new IniSecurityManagerFactory(configFile);

    //2、得到SecurityManager实例 并绑定给SecurityUtils
    org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
    SecurityUtils.setSecurityManager(securityManager);

    //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token = new UsernamePasswordToken(username, password);

    subject.login(token);
    }

    @After
    public void tearDown() throws Exception {
    ThreadContext.unbindSubject();//退出时请解除绑定Subject到线程 否则对下次测试造成影响
    }

    }
  3. 测试用例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    package com.xiaoruiit.shiro.config;

    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authz.UnauthorizedException;
    import org.junit.Assert;
    import org.junit.Test;

    import java.util.Arrays;

    /**
    * @author hxr
    * @Classname AuthorizationTest
    * @Description ToDo
    */
    public class AuthorizationTest extends BaseAuthorizationTest{

    // 基于角色的访问控制(隐式)
    // 1.基于角色的访问控制(隐式)
    @Test
    public void testHasRole(){
    login("classpath:shiro-role.ini", "zhang", "123");
    //判断拥有角色:role1
    ;
    Assert.assertTrue(SecurityUtils.getSubject().hasRole("role1"));
    //判断拥有角色:role1 and role2
    Assert.assertTrue(SecurityUtils.getSubject().hasAllRoles(Arrays.asList("role1", "role2")));
    //判断拥有角色:role1 and role2 and !role3
    boolean[] result = SecurityUtils.getSubject().hasRoles(Arrays.asList("role1", "role2", "role3"));
    Assert.assertEquals(true, result[0]);
    Assert.assertEquals(true, result[1]);
    Assert.assertEquals(false, result[2]);
    }

    // 2.基于角色的访问控制(隐式)
    // checkRole/checkRoles 和 hasRole/hasAllRoles 不同的地方是它在判断为假的情况下会抛出 UnauthorizedException 异常。
    @Test(expected = UnauthorizedException.class)
    public void testCheckRole() {
    login("classpath:shiro-role.ini", "zhang", "123");
    //断言拥有角色:role1
    SecurityUtils.getSubject().checkRole("role1");
    //断言拥有角色:role1 and role3 失败抛出异常
    SecurityUtils.getSubject().checkRoles("role1", "role3");
    }
    }

基于资源的访问控制(显示角色)

  1. 配置shrio-permission.ini

    1
    2
    3
    4
    5
    6
    [users]
    zhang=123,role1,role2
    wang=123,role1
    [roles]
    role1=user:create,user:update
    role2=user:create,user:delete
  2. BaseAuthorizationTest

    同上的BaseAuthorizationTest

  3. 测试类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    package com.xiaoruiit.shiro.config;

    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authz.UnauthorizedException;
    import org.junit.Test;

    /**
    * @author hxr
    * @Classname AuthorizationPermittedTest
    * @Description ToDo
    */
    public class AuthorizationPermittedTest extends BaseAuthorizationTest {

    @Test
    public void testIsPermitted() {
    login("classpath:shiro-permission.ini", "zhang", "123");
    //判断拥有权限:user:create
    boolean permitted = SecurityUtils.getSubject().isPermitted("user:create");
    //判断拥有权限:user:update and user:delete
    boolean permittedAll = SecurityUtils.getSubject().isPermittedAll("user:update", "user:delete");
    //判断没有权限:user:view
    boolean permitted1 = SecurityUtils.getSubject().isPermitted("user:view");

    System.out.println(permitted + " " + permittedAll + " " + permitted1);
    }

    @Test(expected = UnauthorizedException.class)
    public void testCheckPermission () {
    login("classpath:shiro-permission.ini", "zhang", "123");
    //断言拥有权限:user:create
    SecurityUtils.getSubject().checkPermission("user:create");
    //断言拥有权限:user:delete and user:update
    SecurityUtils.getSubject().checkPermissions("user:delete", "user:update");
    //断言拥有权限:user:view 失败抛出异常
    SecurityUtils.getSubject().checkPermissions("user:view");
    // 阻塞了后续代码,即使@Test(expected = UnauthorizedException.class)
    System.out.println(1);

    }
    }