Shiro学习之权限认证

权限认证也就是访问控制,即在应用中控制谁能访问哪些资源.
在权限认证中,最核心的是三个要素是:权限,角色和用户.
权限,即操作资源的权力,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利(CRUD).
角色,是权限的集合,一个角色可以包含多种权限
用户,在shiro中代表访问系统的用户,即subject


授权

  • 编程式授权,基于角色和权限的访问控制
  • 注解授权,jsp标签授权

1.基于角色的访问控制
配置shiro_role.ini文件

[users]
yyt=123,role1,role2
jack=1234,role1

规则即:“用户名=密码,角色1,角色2”,如果需要在应用中判断用户是否有相应角色,就需要在相应的Realm中返回角色信息,也就是说Shiro不负责维护用户-角色信息,需要应用提供,Shiro只是提供相应的接口方便验证,后续会介绍如何动态的获取用户角色。

首先我将重复的代码封装成一个方法,传入配置文件的名字,用户名,密码

package com.kingsky;

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;

public class ShiroUtil {
    public static Subject login(String configPath, String userName,
            String passWord) {
        // 读取配置文件,初始化SecurityManager工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory(
                "classpath:"+configPath);

        // 获取到SecurityManager实例
        SecurityManager securityManager = factory.getInstance();

        // 把SecurityManager绑定到SecurityUtils中

        SecurityUtils.setSecurityManager(securityManager);
        // 得到当前用户
        Subject subject = SecurityUtils.getSubject();

        // 创建Token令牌,用户名/密码
        UsernamePasswordToken passwordToken = new UsernamePasswordToken(userName,
                passWord);
        // 验证登录 会抛出异常
        try {
            subject.login(passwordToken);
            System.out.println("身份验证成功!!!");
        } catch (AuthenticationException e) {
            e.printStackTrace();
            System.out.println("身份验证失败!!!!");
        }
        return subject;
    }
}

在测试类中进行测试,我没有使用junit进行测试,我是直接使用main方法测试
1.1测试subject.hasRole(String roleName) 返回值是boolean

public class TestRole {
    public static void main(String[] args) {
        Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
        //Subject subject=ShiroUtil.login("shiro_role.ini", "jack", "1234");
        System.out.println(subject.hasRole("role2")?"有role2这个角色":"没有role2这个角色");
    }
}

控制台的输出是:有role2这个角色,
如果是换成了jack,控制台输出的是:没有role2这个角色

1.2测试subject.hasRoles(List roles) 返回值是boolean[]

Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
//Subject subject=ShiroUtil.login("shiro_role.ini", "jack", "1234");
boolean[] results=subject.hasRoles(Arrays.asList("role1","role2"));
for (boolean b : results) {
    System.out.println(b);
}

用户是yyt的时候,控制台输出的是:true,true,代表的是yyt拥有role1,role2这个角色
用户是jack的时候,控制台出去的是:true,false,代表的是jack用户role1这个角色,但是没有role2这个角色

1.3测试subject.hasAllRoles(List roles) 返回值是boolean

Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
//Subject subject=ShiroUtil.login("shiro_role.ini", "jack", "1234");
System.out.println(subject.hasAllRoles(Arrays.asList("role1","role2"))?"有role2,role1这个角色":"role1,role2这个角色不全有");

用户是yyt的时候,控制台输出的是:有role2,role1这个角色
用户是jack的时候,控制台出去的是:role1,role2这个角色不全有

1.4测试subject.checkRole(String roleName) 没有返回值,假如验证失败,则会报错:
org.apache.shiro.authz.UnauthorizedException: Subject does not have role [role2]

//Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
Subject subject=ShiroUtil.login("shiro_role.ini", "jack", "1234");
subject.checkRole("role2");

1.5测试subject.checkRoles(String… roleIdentifiers) 可以传入多个角色名称,假如验证失败,则会报错:
org.apache.shiro.authz.UnauthorizedException: Subject does not have role [role2]

Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
//Subject subject=ShiroUtil.login("shiro_role.ini", "jack", "1234");
subject.checkRoles("role2","role1");

1.6测试subject.checkRoles(String… roleIdentifiers) 可以传入多个角色名称,假如验证失败,则会报错:
org.apache.shiro.authz.UnauthorizedException: Subject does not have role [role2]

Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
//Subject subject=ShiroUtil.login("shiro_role.ini", "jack", "1234");
subject.checkRoles(Arrays.asList("role1","role2"));

2.基于权限的控制
配置文件内容如下:shiro-permission.ini

[users]
yyt=123,role1,role2
jack=1234,role1
[roles]
role1=user:create,user:update  
role2=user:create,user:delete

2.1测试subject.isPermitted(String name) 返回boolean

package com.kingsky;

import org.apache.shiro.subject.Subject;

public class TestPermission {
    public static void main(String[] args) {
        // Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
        Subject subject = ShiroUtil.login("shiro-permission.ini", "jack","1234");
        boolean result= subject.isPermitted("user:create");
        System.out.println(result?"有user:create这个权限":"没有user:create这个权限");
    }
}

控制台输出:有user:create这个权限,假如权限名称改为:user:delete则输出的没有这个权限

2.2测试subject.isPermittedAll(String… names) 返回boolean,代表是全有或者不全有这些权限

// Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
Subject subject = ShiroUtil.login("shiro-permission.ini", "jack","1234");
boolean result=subject.isPermittedAll("user:create","user:delete");
System.out.println(result?"有user:create,update这些权限":"这些user:create,update权限不全有");

控制台输出:有user:create,update这些权限
假如修改权限:user:delete,则会返回fase

2.3测试subject.isPermitted(String… names) 返回boolean[],对应的权限是不是有

// Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
Subject subject = ShiroUtil.login("shiro-permission.ini", "jack","1234");
boolean results[]=subject.isPermitted("user:create","user:delete");
for (boolean b : results) {
    System.out.println(b);
}

控制台输出:true(代表user:create有权限),false(代表user:delete没有权限)

2.4测试subject.checkPermission(String name);没有返回值,但是验证不成功则会报错:
org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [user:delete]

// Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
Subject subject = ShiroUtil.login("shiro-permission.ini", "jack","1234");
subject.checkPermission("user:delete");

2.5测试subject.checkPermissions(Stirng… names);没有返回值,但是验证不成功则会报错:
org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [user:delete]

// Subject subject=ShiroUtil.login("shiro_role.ini", "yyt", "123");
Subject subject = ShiroUtil.login("shiro-permission.ini", "jack","1234");
subject.checkPermissions("user:create","user:update");

3.注解授权,jsp标签授权
在JSP页面通过相应的标签完成:

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

4、Shiro对权限字符串缺失部分的处理
如“user:view”等价于“user:view:”;而“organization”等价于“organization:”或者“organization::”。可以这么理解,这种方式实现了前缀匹配。
另外如“user:”可以匹配如“user:delete”、“user:delete”可以匹配如“user:delete:1”、“user::1”可以匹配如“user:view:1”、“user”可以匹配“user:view”或“user:view:1”等。即_可以匹配所有,不加_可以进行前缀匹配;但是如“:view”不能匹配“system:user:view”,需要使用“:_:view”,即后缀匹配必须指定前缀(多个冒号就需要多个_来匹配)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Shiro框架可以按照以下步骤进行: 1. 了解基础概念:首先,你需要了解Shiro的基本概念和术语,例如主体(Subject)、认证(Authentication)、授权(Authorization)、Realm等。可以阅读Shiro的官方文档或者相关的教程来获得这些知识。 2. 安装和配置:安装Shiro框架并进行基本的配置。你可以在Shiro的官方网站上找到安装指南和配置示例。 3. 认证功能:学习如何使用Shiro进行用户认证,包括用户名密码认证、Remember Me功能、多Realm认证等。可以尝试编写简单的认证示例来理解这些功能。 4. 授权功能:学习如何使用Shiro进行用户授权,包括角色授权和权限授权。了解如何定义角色和权限,并且如何在代码中进行授权判断。 5. Session管理:了解Shiro如何管理用户的会话信息,包括会话超时、会话验证等。学习如何使用Shiro提供的Session API来管理会话。 6. 整合框架:如果你使用其他的Java框架,例如Spring或者Spring Boot,学习如何将Shiro与这些框架进行整合,以便更好地利用Shiro的功能。 7. 安全性优化:深入了解Shiro的安全性能优化技巧,例如密码加密、安全配置、防止常见安全漏洞等。 8. 实战练习:通过编写实际的应用程序来巩固所学的知识。可以尝试开发一个简单的Web应用程序,使用Shiro进行用户认证和授权。 除了官方文档和教程,还可以参考一些优秀的书籍或在线教程,例如《Apache Shiro官方指南》、《深入浅出Shiro安全框架》等。此外,加入Shiro的社区或者论坛,与其他开发者交流经验也是一个很好的学习方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值