Shiro入门学习四

Shiro入门学习四

授权

授权流程
授权流程参考官网Authorization Sequence,也可参阅第三章 授权——《跟我学Shiro》

这里写图片描述

流程如下:

  1. 首先调用Subject.isPermitted*/hasRole*接口,其会委托给SecurityManager,而SecurityManager接着会委托给Authorizer;
  2. Authorizer是真正的授权者,如果我们调用如isPermitted(“user:view”),其首先会通过PermissionResolver把字符串转换成相应的Permission实例;
  3. 在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限;
  4. Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托给ModularRealmAuthorizer进行循环判断,如果匹配如isPermitted*/hasRole*会返回true,否则返回false表示授权失败。

在授权中需了解的几个关键对象:

  • 主提(subject):即访问应用的用户,在Shiro中使用Subject代表该用户
  • 资源(resources):在应用中用户可以访问的任何东西
  • 权限:对某个资源的细粒度的CRUD
  • 角色:角色代表了操作集合,可以理解为权限的集合

JavaSE例子

角色

shiro.ini文件中,添加如下的内容,配置用户拥有的角色:

[users]
kh=123,r1,r2
zhangsan=111,r3
lisi=123,r2,r3

测试如下:

    public Subject login(String username, String password) {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);

        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
            return subject;
        } catch (UnknownAccountException e) {
            System.out.println("用户不存在");
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码不存在");
        } catch (AuthenticationException e) {
            System.out.println("认证异常");
        }
        return null;
    }

    @Test
    public void testRole() {
        Subject subject = login("kh", "123");
        System.out.println(subject.hasRole("r1"));
        System.out.println(subject.hasAllRoles(Arrays.asList("r1","r2","r3")));
        System.out.println(subject.hasRoles(Arrays.asList("r1","r2","r3"))[2]);
        subject.checkRole("r1");
    }

做一些说明:

1.hasRole("r1")是否有r1角色,返回值为boolean
2.hasAllRoles是否有所有的权限,返回值为boolean
3.hasRoles返回值为boolean为数组
4.checkRole方法没有返回值,如果没有对应的角色,则抛异常

权限

如下配置权限:

[roles]
r1=user:create,user:delete
r2=topic:*
  • r1=user:create,user:delete表示r1具有user的create,delete权限,可简写为r1="user:create,delete"(注意带有引号)
  • r2=topic:*表示r2具有topic的所有权限

测试如下:

    @Test
    public void testPermission() {
        Subject subject = login("kh", "123");
        // 是否具有user的view权限 false
        System.out.println(subject.isPermitted("user:view"));
        // 是否具有user的delete权限 true
        System.out.println(subject.isPermitted("user:delete"));
        // 是否具有topic的create权限 true
        System.out.println(subject.isPermitted("topic:create"));
    }

如下的r1:

r1="user:create,delete","dep:del,view",classroom

classroom等同于classroom:*

r3=*:view表示r3具有任何的view的权限,如test:view,但test:abc:view则不行

自定义realm中权限的处理

可参考在Spring MVC中使用Apache Shiro安全框架

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录时输入的用户名
        String loginName = (String) principalCollection.fromRealm(getName()).iterator().next();
        //到数据库查是否有此对象
        User user = this.getDao().findByName(loginName);
        if (user != null) {
            //权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //用户的角色集合
            info.setRoles(user.getRolesName());
            //用户的角色对应的所有权限,如果只使用角色定义访问权限,下面的四行可以不要
            List<Role> roleList = user.getRoleList();
            for (Role role : roleList) {
                info.addStringPermissions(role.getPermissionsString());
            }
            return info;
        }
        return null;
    }

授权推荐教程

加密

参阅第五章 编码/加密——《跟我学Shiro》

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5、SHA等

        //202cb962ac59075b964b07152d234b70
        System.out.println(new Md5Hash("123").toHex());
        //ICy5YqxZB1uWSwcVLSNLcA==
        System.out.println(new Md5Hash("123").toBase64());

一般进行散列时最好提供一个salt(盐),比如加密密码“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一些md5解密网站很容易的通过散列值得到密码“admin”,即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,如用户名和ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。

String str = "hello";  
String salt = "123";  
String md5 = new Md5Hash(str, salt).toString();//还可以转换为 toBase64()/toHex() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值