初试Shiro

news2024/11/14 9:16:03

Shiro是一个用于身份验证、授权和会话管理的Java安全框架。它提供了一套易于使用的API,可以帮助开发人员构建安全性强大的应用程序。

环境准备

添加依赖

       <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.9.0</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

INI 文件

Shiro 获取权限相关信息可以通过数据库获取,也 可以通过 ini 配置文件获取。
[users]
zhangsan=z3
lisi=l4

登录认证 

登录认证概念

  • 身份验证:一般需要提供如身份ID等一些标识信息来表明登录者的身份,如提供email,用户名/密码来证明。
  • 在shiro中,用户需要提供principals(身份)和credentials(证明)给shiro,从而应用能验证用户身份:
  • principals:身份,即主体的标识属性,可以是任何属性,如用户名、邮箱等,唯一即可。一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/邮箱/手机号。
  • credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。
  • 最常见的principals和credentials组合就是用户名/密码

登录认证基本流程 

  • 收集用户身份/凭证,即如用户名/密码
  • 调用 Subject.login 进行登录,如果失败将得到相应 的 AuthenticationException异常,根据异常提示用户 错误信息;否则登录成功
  • 创建自定义的 Realm 类,继承 org.apache.shiro.realm.AuthenticatingRealm类,实现 doGetAuthenticationInfo() 方法

登录认证实例

创建测试类,获取认证对象,进行登录认证,如下:
public class ShiroRun {
    public static void main(String[] args) {
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = (SecurityManager) factory.getInstance();
        SecurityUtils.setSecurityManager((SecurityManager) securityManager);
        //2 获取 Subject 对象
        Subject subject = SecurityUtils.getSubject();
        //3 创建 token 对象,web 应用用户名密码从页面传递
        AuthenticationToken token = new UsernamePasswordToken("zhangsan","z3");
        //4 完成登录
        try {
            subject.login(token);
            System.out.println("登录成功");
        }
        catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户不存在");
        }
        catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误");
        }
        catch (AuthenticationException ae) {
            //unexpected condition? error?
        }
    }
}

身份认证流程

  1. 首先调用 Subject.login(token) 进行登录,其会自动委托给 SecurityManager
  2. SecurityManager 负责真正的身份验证逻辑;它会委托给 Authenticator 进行身份验证;
  3. Authenticator 才是真正的身份验证者,Shiro API 中核心的身份 认证入口点,此处可以自定义插入自己的实现;
  4. Authenticator 可能会委托给相应的 AuthenticationStrategy 进 行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用 AuthenticationStrategy 进行多 Realm身份验证;
  5.  Authenticator 会把相应的 token 传入 Realm,从 Realm 获取 身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处 可以配置多个Realm,将按照相应的顺序及策略进行访问。

测试

角色授权 

授权概念

  • 授权,也叫访问控制,即在应用中控制谁访问哪些资源(如访问页面/编辑数据/页面操作 等)。在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限 (Permission)、角色(Role)。
  • 主体(Subject):访问应用的用户,在 Shiro 中使用 Subject 代表该用户。用户只有授权 后才允许访问相应的资源。
  • 资源(Resource)在应用中用户可以访问的 URL,比如访问 JSP 页面、查看/编辑某些 数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问。
  • 权限(Permission):安全策略中的原子授权单位,通过权限我们可以表示在应用中用户 有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源,如:访问用 户列表页面查看/新增/修改/删除用户数据(即很多时候都是CRUD(增查改删)式权限控 制)等。权限代表了用户有没有操作某个资源的权利,即反映在某个资源上的操作允不允 许。
  • Shiro 支持粗粒度权限(如用户模块的所有权限)和细粒度权限(操作某个用户的权限, 即实例级别的)
  • 角色(Role)权限的集合,一般情况下会赋予用户角色而不是权限,即这样用户可以拥有 一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、CTO、开发工程师等 都是角色,不同的角色拥有一组不同的权限

授权方式 

编程式:通过写if/else 授权代码块完成
if (subject.hasRole("admin")) {
     // 有权限
}else {
     // 无权限
}
注解式:通过在执行的Java方法上放置相应的注解完成,没有权限将抛出相 应的异常
@RequiresRoles("admin")
public void hello(){
    // 有权限
}

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

授权流程 

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

授权实例

获取角色信息
// 给shiro.ini增加角色配置
[users]
zhangsan=z3,role1,role2
lisi=l4
给例子添加代码,沟通过hasRole()判断用户是否有指定角色
 try {
            subject.login(token);
            System.out.println("登录成功");
            // 判断角色
            boolean role1 = subject.hasRole("role1");
            System.out.println("师范拥有此角色" + role1);
}
判断权限信息信息
// 给shiro.ini增加权限配置
[roles]
role1=user:insert,user:select
给例子添加代码,判断用户是否有指定权限
//判断权限
boolean isPermitted = subject.isPermitted("user:insert");
System.out.println("是否拥有此权限:"+isPermitted);
//也可以用 checkPermission 方法,但没有返回值,没权限抛 AuthenticationException
subject.checkPermission("user:select");

测试

Shiro加密

实际系统开发中,一些敏感信息需要进行加密,比如说用户的密码。Shiro 内嵌很多常用的加密算法,比如 MD5 加密。Shiro 可以很简单的使用信息加密。

使用Shiro进行密码加密

import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;

public class ShiroMD {
    public static void main(String[] args) {
        //密码明文
        String password = "z3";
        //使用 md5 加密
        Md5Hash md5Hash = new Md5Hash(password);
        System.out.println("md5 加密:"+md5Hash.toHex());
        //带盐的 md5 加密,盐就是在密码明文后拼接新字符串,然后再进行加密
        Md5Hash md5Hash2 = new Md5Hash(password,"salt");
        System.out.println("md5 带盐加密:"+md5Hash2.toHex());
        //为了保证安全,避免被破解还可以多次迭代加密,保证数据安全
        Md5Hash md5Hash3 = new Md5Hash(password,"salt",3);
        System.out.println("md5 带盐三次加密:"+md5Hash3.toHex());
        //使用父类实现加密
        SimpleHash simpleHash = new SimpleHash("MD5",password,"salt",3);
        System.out.println("父类带盐三次加密:"+simpleHash.toHex());
    }
}

Shiro 自定义登录认证

Shiro 默认的登录认证是不带加密的,如果想要实现加密认证需要自定义登录认证,自定义 Realm。

自定义登录认证

public class MyRealm extends AuthenticatingRealm {
    //自定义的登录认证方法,Shiro 的 login 方法底层会调用该类的认证方法完成登录认证
    //需要配置自定义的 realm 生效,在 ini 文件中配置,或 Springboot 中配置
    //该方法只是获取进行对比的信息,认证逻辑还是按照 Shiro 的底层认证逻辑完成认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1 获取身份信息
        String principal = authenticationToken.getPrincipal().toString();
        //2 获取凭证信息
        String password = new String((char[]) 
       authenticationToken.getCredentials());
        System.out.println("认证用户信息:"+principal+"---"+password);
        //3 获取数据库中存储的用户信息
        if(principal.equals("zhangsan")){
          //3.1 数据库存储的加盐迭代 3 次密码
          String pwdInfo = "7174f64b13022acd3c56e2781e098a5f";
          //3.2 创建封装了校验逻辑的对象,将要比较的数据给该对象
          AuthenticationInfo info = new SimpleAuthenticationInfo(
          authenticationToken.getPrincipal(),
          pwdInfo,
          ByteSource.Util.bytes("salt"),
          authenticationToken.getPrincipal().toString());
          return info;
        }
        return null;
    }
}

在shiro.ini中添加配置信息

[main]
md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations=3
myrealm=com.example.demo.component.MyRealm
myrealm.credentialsMatcher=$md5CredentialsMatcher
securityManager.realms=$realm
[users]
zhangsan=7174f64b13022acd3c56e2781e098a5f,role1,
role2
lisi=l4
[roles]
role1=user:insert,user:select

参数:

  • md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher:这行配置指定了使用MD5算法进行凭证匹配的CredentialsMatcher实现类。

  • md5CredentialsMatcher.hashIterations=3:这行配置指定了MD5算法的哈希迭代次数,即将密码哈希化的循环次数。

  • myrealm=com.example.demo.component.MyRealm:这行配置指定了自定义的Realm实现类,即MyRealm。

  • myrealm.credentialsMatcher=$md5CredentialsMatcher:这行配置将之前定义的md5CredentialsMatcher赋值给MyRealm的凭证匹配器(credentialsMatcher)属性。

  • securityManager.realms=$myrealm:这行配置将MyRealm添加到SecurityManager中的Realms列表中。

测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1133703.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vueDay04——v-if else show

一、v-if的使用 我们可以像c语言一样去使用v-if结构 比如单用v-if&#xff0c;连用v-if v-else&#xff0c;或者是v-if v-else-if v-else 注意&#xff1a; 1.v-if v-else-if需要绑定值,而v-else不需要绑定值 2.if结构可以用在不同的标签类型之间 <div v-if"fir…

【MATLAB源码-第57期】基于matlab的IS95前向链路仿真,输出误码率曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 IS-95&#xff0c;也被称为cdmaOne&#xff0c;是第一代的CDMA&#xff08;Code Division Multiple Access&#xff0c;码分多址&#xff09;数字蜂窝通信标准。IS-95的全称是Interim Standard-95&#xff0c;最初由Qualcomm…

灵活、可用、高扩展,EasyMR 带来全新 Yarn 的队列管理功能及可视化配置

YARN&#xff08;Yet Another Resource Negotiator&#xff09;是 Hadoop 生态系统中的资源调度器&#xff0c;主要用于资源管理和作业调度。YARN 自身具备队列管理功能&#xff0c;通过对 YARN 资源队列进行配置和管理&#xff0c;实现集群资源的分配&#xff0c;以满足不同应…

Doceker-compose——容器群集编排管理工具

目录 Docker-compose 1、Docker-compose 的三大概念 2、YAML文件格式及编写注意事项 1&#xff09;使用 YAML 时需要注意下面事项 2&#xff09;ymal文件格式 3&#xff09;json格式 3、Docker Compose配置常用字段 4、Docker-compose的四种重启策略 5、Docker Compos…

[微服务]Spring Cloud Sleuth全链路追踪

Spring Cloud Sleuth全链路追踪 全链路追踪组件追踪的数据遵循的规则: 1,Span:基本单元; 执行一次服务调用就生成一个span,用于记录当时的情况 ,以一个64位ID作为唯一标识.span还有其他数据标识如摘要,时间戳信息,关键tag等; 2,Trace:一次请求; 以一个64位ID为唯一标识,可以…

各品牌PLC存储器寻址的规则

在PLC编程时&#xff0c;字节或多字节的变量一般支持绝对地址寻址&#xff08;比如&#xff0c;IW0、MD4等&#xff09;。要想正确寻址&#xff0c;则必须要搞清楚寻址的规则。目前常见的规则有两种&#xff1a;字节寻址和字寻址。下图清晰地表达了两种规则的编号情况&#xff…

AI:WEB 1 靶机

1.找ip地址 2.检测端口 3.上文件检索 发现是apache 的组件 4.漏洞扫描攻击 nikto -h 网站 扫描网站漏洞 目录爆破 5.利用发现敏感目录 6.登录 发现 都是403 使用上层发现ok 这是一个查询功能点 7.敏感目录 sql注入 检验 详细信息 检测到注入方式 查看数…

系统架构设计师之RUP软件开发生命周期

系统架构设计师之RUP软件开发生命周期

EasyAR使用

EazyAR后台管理&#xff0c;云定位服务 建模 需要自行拍摄360度视频&#xff0c;后台上传&#xff0c;由EazyAR工作人员完成构建。 标注数据 需要在unity安装EazyAR插件&#xff0c;在unity场景编辑后&#xff0c;上传标注数据。 uinity标注数据 微信小程序中使用&#x…

Kali Linux 安装使用远程桌面连接远程服务器

1. 安装远程桌面连接软件 目前为止&#xff0c;我们已经可以通过其它机器以远程桌面的方式连接 Kali Linux&#xff0c;但想要使用 Kali Linux 远程连接其它机器还无法做到&#xff0c;下面就看看如何实现。 更新软件源列表&#xff1b; $ sudo apt-get update $ sudo apt-g…

二、可行性分析与需求分析

文章目录 概念考点练习题一、可行性分析与需求分析1.可行性分析的任务2.可行性研究3.甘特图4.数据流图5.数据字典数据字典的内容 6.需求分析7. 实体联系ER图8. 状态转换图 二、练习题 概念考点练习题 一、可行性分析与需求分析 1.可行性分析的任务 用最小的代价在尽可能短的时…

Xilinx MicroBlaze定时器中断无法返回主函数问题解决

最近在使用Xilinx 7系列FPGA XC7A100T时&#xff0c;运行MicroBlaze软核处理器&#xff0c;添加了AXI TIMER IP核&#xff0c;并使能定时器溢出中断&#xff0c;发现定时器触发中断后&#xff0c;无法返回主函数的问题&#xff0c;最后发现修改编译器优化等级就正常了。 FPGA型…

量子力学的基础公设

量子力学的基础公设 - 知乎

MySQL---JDBC编程

文章目录 什么是JDBC&#xff1f;JDBC的工作原理JDBC的使用添加依赖创建数据源DataSource创建数据库连接Connection创建操作命令Statement执行SQL指令释放资源 通过JDBC演示CRUD新增查询修改删除 什么是JDBC&#xff1f; JDBC&#xff1a;Java Database Connectivity&#xff…

10000阅读量感言

目录 前言 10000阅读量 回忆 感谢 结尾 前言 2023年10月25日20点26分&#xff0c;我终于突破10000阅读量了&#xff01;为了记录下来&#xff0c;我写下了这篇博客。 10000阅读量 以上是我卡点截的一张图&#xff0c;我当时看到自己10000阅读量还是很惊喜的&#xff0c;还…

算法训练营第一天 704 .二分查找、27.移除元素

算法训练营第一天 | 704 .二分查找、27.移除元素 &#xff08; 一 &#xff09;、704 二分查找 题目链接&#xff1a;https://leetcode.cn/problems/binary-search/description/ 解题思路&#xff1a; ​ 数组 nums 是有序排列的&#xff0c;二分查找每次都是对半查询&…

【离散数学必刷题】命题逻辑(第一章 左孝凌)刷完包过!

复习16题&#xff1a; 【1】下列哪个语句是真命题&#xff08;&#xff09; A、今天天气真好&#xff01; B、我正在说谎。 C、如果7 2 10 &#xff0c;那么4 6 5。 D、如果7 2 9 &#xff0c; 则 4 6 5。 对于A&#xff0c;只有具有确定真值的陈述句才是命题&#xf…

TotalFinder v1.15.1(Finder代替工具)

TotalFinder是一款功能强大的文件管理工具&#xff0c;为Mac用户提供了一整套增强的文件管理功能和工具&#xff0c;能够更高效地管理和组织文件。 TotalFinder的主要特点包括&#xff1a; 为Finder添加了选项卡功能&#xff0c;允许多个文件夹在同一个窗口中同时打开。用户可…

一文精通C++ -- 继承

前言&#xff1a;继承是C类和对象三大特性中关键的一环&#xff0c;上承封装&#xff0c;下接多态&#xff0c;C中的继承是一种面向对象编程的概念&#xff0c;它允许一个类&#xff08;称为子类或派生类&#xff09;继承另一个类&#xff08;称为父类或基类&#xff09;的属性…

Java常见限流方式

Java常见限流方式 1、计数限流2、固定窗口限流3、滑动窗口限流4、漏桶算法5、令牌桶算法 1、计数限流 例如系统能同时处理 100 个请求&#xff0c;保存一个计数器&#xff0c;处理了一个请求&#xff0c;计数器就加一&#xff0c;一个请求处理完毕之后计数器减一。 每次请求来…