Shiro权限控制

article/2025/9/19 20:16:43

目录

  • 认识Shiro的整体架构,各组件的概念
    • 简介
    • Shiro与Spring Security比较
    • Shiro整体架构
  • Shiro认证,授权的过程
    • shiro认证
    • Shiro授权
  • Shiro自定义的Realm,Filter
    • IniRealm配置文件
    • JdbcRealm
    • 自定义Realm
    • shiro加密
  • Shiro Session管理
  • Shiro 缓存管理
  • Shiro集成Spring
    • shiro集成spring
    • 通过注解的方式配置角色权限
    • shiro过滤器

认识Shiro的整体架构,各组件的概念

简介

  • Apache 的强大灵活的开源安全框架;
  • 认证、授权、企业会话管理、安全加密;

Shiro与Spring Security比较

Apache ShiroSpring Security
简单灵活复杂笨重
可脱离Spring不可脱离Spring
粒度较粗粒度更细

Shiro整体架构

Shiro通过Security Manager提供安全服务
Security Manager管理着其他组件的实例

  1. Authenticator(认证器):管理登录,登出
  2. Authorizer(授权器):赋予主体权限
  3. Session Manager(Session管理器):Shiro自己实现的管理机制,不借用任何容器使用Session
  4. Session Dao(提供Session的操作):主要有:增删改查。
  5. Cache Manager(缓存管理器):角色和权限数据缓存。
  6. Pauggable Realms(数据库与数据源的桥梁):shiro获取数据是通过realms来获取的。

流程:

  1. 主体提交请求到Security Manager.
  2. Security Manager调用Authenticator进行认证。(Authenticator认证获取数据是通过realms获取的,再从数据源中获取信息)数据源信息和主体提交的信息比对。
  3. (Authorizer授权获取数据是通过realms获取的,再从数据源中获取数据)数据源信息和主体提交的信息做比对。
  4. 数据加密
    在这里插入图片描述

Shiro认证,授权的过程

shiro认证

Shiro安全认证简单流程如图:

  1. 构建SecurityManager环境
  2. 主体提交认证请求
  3. SecurityManager认证
  4. Authenticator认证
  5. Realm验证(用户名,密码信息)

注:3,4,5步认证在主体提交认证里面

package org.example;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;public class AuthenticationTest {public SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();@Beforepublic void addUser(){simpleAccountRealm.addAccount("mark", "123456");}@Testpublic void testAuthentication(){//1.构建SecurityManager环境DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();defaultSecurityManager.setRealm(simpleAccountRealm);//2. 主体提交认证请求SecurityUtils.setSecurityManager(defaultSecurityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("mark", "123456");subject.login(token);System.out.println("isAuthenticated:" + subject.isAuthenticated());}
}

Shiro授权

Shiro授权
与之前Shiro认证的步骤一样。
只不过在Realm 的SimpleAccountRealm中可以添加addUser的时候,可以添加入多个角色(即可变数组的形式)
同样进行授权验证即检验该登录用户是否具备该角色的时候,使用:
subject.checkRoles(可变参数)的形式检验。
必须在登录的情况下,其他步骤与认证相同。

package org.example;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;public class AuthenticationTest {public SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();@Beforepublic void addUser(){simpleAccountRealm.addAccount("mark", "123456", "admin", "user");}@Testpublic void testAuthentication(){//1.构建SecurityManager环境DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();defaultSecurityManager.setRealm(simpleAccountRealm);//2. 主体提交认证请求SecurityUtils.setSecurityManager(defaultSecurityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("mark", "123456");subject.login(token);System.out.println("isAuthenticated:" + subject.isAuthenticated());subject.checkRoles("admin", "user");}
}

Shiro自定义的Realm,Filter

IniRealm配置文件

IniRealm就是把 realm 的信息以.ini的配置文件形式保存,
其他的和认证授权没啥区别

package org.example;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;public class IniRealmTest {@Testpublic void testAuthentication(){//获取realm配置文件IniRealm iniRealm = new IniRealm("classpath:user.ini");//1.构建SecurityManager环境DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();defaultSecurityManager.setRealm(iniRealm);//2. 主体提交认证请求SecurityUtils.setSecurityManager(defaultSecurityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("mark", "123456");subject.login(token);System.out.println("isAuthenticated:" + subject.isAuthenticated());subject.checkRoles("admin", "user");}}

ini配置文件

[users]
mark=123456,admin,user
[roles]
admin=user:delete,user:update

JdbcRealm

JdbcRealm就是把 realm 的信息从数据库里去查找,默认有一些JdbcRealm自带有一些默认的SQL。realm的信息主要有用户信息users角色信息user_roles角色的权限信息roles_permissions
验证信息的SQL也可以自定义编写
注意:权限校验要在jdbcRealm里开启权限

package org.example;import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;public class JdbcRealmTest {DruidDataSource dataSource = new DruidDataSource();{dataSource.setUrl("jdbc:mysql://localhost:3306/shiro_demo?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true");dataSource.setUsername("root");dataSource.setPassword("root");}@Testpublic void testAuthentication(){JdbcRealm jdbcRealm = new JdbcRealm();jdbcRealm.setDataSource(dataSource);jdbcRealm.setPermissionsLookupEnabled(true);//自定义用户信息验证SQLString userSql = "select password from users_test where username= ?";jdbcRealm.setAuthenticationQuery(userSql);//自定义角色验证SQLString roleSql = "select role_name from user_roles_test where username = ?";jdbcRealm.setUserRolesQuery(roleSql);//自定义角色权限验证SQLString permissionSql = "select permission from roles_permissions_test where role_name =?";jdbcRealm.setPermissionsQuery(permissionSql);//1.构建SecurityManager环境DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();defaultSecurityManager.setRealm(jdbcRealm);//2. 主体提交认证请求SecurityUtils.setSecurityManager(defaultSecurityManager);Subject subject = SecurityUtils.getSubject();//        UsernamePasswordToken token = new UsernamePasswordToken("mark", "123456");UsernamePasswordToken token = new UsernamePasswordToken("rose", "111222");subject.login(token);System.out.println("isAuthenticated:" + subject.isAuthenticated());//        subject.checkRoles("admin");subject.checkRoles("user");//        subject.checkPermission("user:select");subject.checkPermission("user:update");}}

自定义Realm

自定义的realm,要注意以下几个步骤:

  1. 首先继承并实现类AuthorizingRealm的方法。其中方法doGetAuthenticationInfo主要做认证操作,即可以通过用户名,查询出相应的密码,然后将用户名与密码一同返回,shiro会自动根据传入的用户名和密码与此realm返回的用户名和密码做比对,返回你想要的结果。
    同理,doGetAuthorizationInfo主要是用来做角色和权限的验证,也是通过用户名,从数据库中查找到相应的角色或者权限的数据并返回一个simple的授权类,授权系统会根据传入的参数与返回的结果集对比,存在返回TRUE,不存在则抛出异常。
  2. 两者方法只能获取用户名称,通过用户名称连接数据库获取其他信息。这里只是做数据准备操作,并不做判断是否传入的值与其相符的操作,此操作在此之后进行
  3. 根据两者的返回对象分别返回simple类型的对象。认证的对象需要将你获取的用户名和密码放到改造方法中。授权对象需要set到相应的方法中。
package org.example.config;import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;public class CustomRealm extends AuthorizingRealm {Map<String, String> usermap = new HashMap<String, String>();{usermap.put("mark", "123456");super.setName("customRealm");}protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String username = (String) principalCollection.getPrimaryPrincipal();//从数据库缓存中获取角色数据Set<String> roles = getRolesByUserName(username);//获取用户权限Set<String> permissions = getPermissionsByUserName(username);SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.setRoles(roles);simpleAuthorizationInfo.setStringPermissions(permissions);return simpleAuthorizationInfo;}private Set<String> getPermissionsByUserName(String userName) {Set<String> sets = new HashSet<String>();sets.add("user:delete");sets.add("user:add");return sets;}private Set<String> getRolesByUserName(String username) {Set<String> sets = new HashSet<String>();sets.add("admin");sets.add("user");return sets;}protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//1.从主体传过来的认证信息中,获得用户名String userName = (String) authenticationToken.getPrincipal();//2.通过用户名从数据库中获取凭证String password = getPasswordUsername(userName);if (password == null) {return null;}SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo("Mark", password, "customRealm");return authenticationInfo;}//模拟数据库查询凭证public String getPasswordUsername(String username){return usermap.get(username);}}

shiro加密

Shiro散列配置

  • HashedCredentialsMatcher
    通过HashedCredentialsMaster的方式加密,创建对象,并设置加密次数以及加密名称,将此加密对象设置到Realm的setCredentialsmaster的方法中,即该Realm采用此密码加密的方式。
    后台的密码采用MD5的hash码值来存储。
    在这里插入图片描述

  • 盐的使用
    加盐的意思就是在密码中拼接其他字符串,组成一个新的密码,然后对这个密码进行md5加密。同时,可以在自定义realm里面的doGetAuthenticationInfo方法进行设置盐进行解密
    在这里插入图片描述

在这里插入图片描述

Shiro Session管理

Shiro 缓存管理

Shiro集成Spring

shiro集成spring

1,引入jar包

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.8</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.8</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.8.0</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.8.0</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.8.0</version></dependency>

2,新建一个xml文件配置shiro主体

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><property name="loginUrl" value="login.html"/><property name="unauthorizedUrl" value="403.html" /><property name="filterChainDefinitions" ><value>/login.html = anon/subLogin = anon/* = authc</value></property></bean><!--    创建SecurityManager对象--><bean class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" id="securityManager"><property name="realm" ref="realm" /></bean><bean id="realm" class="org.example.shiro.realm.CustomRealm" ><property name="credentialsMatcher" ref="credentialsMatcher"/></bean><!--设置加密的算法--><bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"id="credentialsMatcher"><property name="hashAlgorithmName" value="md5"/><property name="hashIterations" value="1"/></bean></beans>

通过注解的方式配置角色权限

  1. 开启aop设置TRUE;
  2. 添加LifecycleBeanPostProcessor;
  3. 添加AuthorizationAttributeSourceAdvisor
<aop:config proxy-target-class="true" /><bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /><bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager" /></bean>
  1. 接口上面配置注解
    @RequestMapping(value = "/test", method = RequestMethod.GET)@ResponseBody@RequiresRoles("admin")public String testRoles() {return "access";}@RequestMapping(value = "/test", method = RequestMethod.GET)@ResponseBody@RequiresPermissions("add")public String testPermissions() {return "access";}

shiro过滤器

shiro内置过滤器
角色相关:

  • anon 代表无需权限
  • authBasic
  • authc 代表需要认证才能访问
  • user 代表需要存在用户对象才能访问
  • logout 登录退出才能访问

权限相关:

  • perms 拥有权限才能被访问
  • roles 拥有角色才能被访问
  • ssl
  • port 相应端口号才能访问
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><property name="loginUrl" value="login.html"/><property name="unauthorizedUrl" value="403.html" /><property name="filterChainDefinitions" ><value>/login.html = anon/subLogin = anon/testRole = roles["admin"]/testRole1 = roles["admin","admin1"]/testPerms = perms["user:delete"]/testPerms1 = perms["user:delete","user:update"]/* = authc</value></property>

http://chatgpt.dhexx.cn/article/hZFqLLaJ.shtml

相关文章

Shiro权限管理框架详解

1 权限管理1.1 什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。 权限管理包括用户身份认证和授权两部分,简称认证授权…

Shiro 权限管理

一共5个表 用户表角色表权限表用户角色中间表角色权限中间表 权限验证 用户不跟权限直接关联&#xff0c; 可以给用户多个角色&#xff0c; 每个角色都有对应的权限&#xff0c;所以给用户加一个角色&#xff0c;就相当于&#xff0c;给用户赋了对应的权限。一个用户可以有多…

Shiro: 权限管理

一、权限管理 1、什么是权限管理 权限管理属于系统安全的范畴&#xff0c;权限管理实现对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问且只能访问自己被授权的资源。   权限管理包括用户身份认证和授权两部分&#xff0c;简称认证授权。对于需要…

【权限管理框架】一文看懂Shiro权限管理框架!

文章目录 1.JavaWeb中的权限控制2.权限框架核心知识ACL和RBAC2.1.ACL和RBAC简介2.2主流权限框架介绍 3.Shiro架构和基本概念3.1.Shiro的4大核心模块3.2.Shiro权限控制运行流程 4.Shiro简单API案例4.1.项目搭建所需依赖4.2.Shiro认证简单实操4.3.Shiro授权简单实操 5.安全数据来…

【端口扫描工具】nmap核心使用方法

目录 nmap的基础使用&#xff1a; 1.1、常用命令参数&#xff1a; 命令格式&#xff1a; 主机发现&#xff1a; 扫描 扫描速度 扫描端口 1.2、基本扫描 1.3、自定义端口扫描 1.4、Ping扫描 1.5、路由追踪 1.6、扫描网段,C段 1.7、操作系统类型的探测 1.8、nmap万能…

【安全工具】Nmap基本使用方法

Nmap工具介绍 Nmap是一款开放源代码的网络探测和安全审核工具&#xff0c;它被设计用来快速扫描大型网络、包括主机探测与发现、开放的端口情况、操作系统与应用服务指纹、WAF识别及常见安全漏洞。 它的图形化界面是 Zenmap、分布式框架为 Dnmap Nmap功能 主机探测&#xf…

nmap工具使用方法

nmap工具使用方法 简介 Nmap&#xff08;网络映射器&#xff09;是一个用于网络探索和安全审计的开源工具 常用扫描端口命令 <nmap -sV 192.168.204.64> -sV&#xff1a;探测端口服务版本<nmap -T4 -A -v 192.168.204.64> -T4&#xff1a; 指定扫描过程使用的时…

nmap使用方法--方便自己查

在侦查期间&#xff0c;扫描一直是信息收集的初始阶段。 什么是侦查 侦查是尽可能多收集关于目标网络的信息。从黑客的角度来看&#xff0c;信息收集对于一次攻击非常有用&#xff0c;所以为了封锁恶意的企图&#xff0c;渗透测试者通常尽力查找这些信息&#xff0c;发现后修复…

端口扫描工具Nmap使用方法 day02

nmap是一个网络端口扫描软件&#xff0c;用来扫描网上电脑开放的网络连接端口&#xff0c;确定哪些服务运行在哪些端口&#xff0c;并且推断计算机运行哪个os。它是网络管理员必用的软件之一&#xff0c;渗透测试人员也可以用它评估网络系统安全。下面介绍kali linux中nmap的用…

nmap详细使用教程

目录 nmap简介 nmap常用命令 实例演示-发现主机 实例演示-端口发现 实例演示-获得服务版本详细信息 实例演示-确定主机操作系统 nmap简介 nmap是一款非常强大的主机发现和端口扫描工具&#xff0c;而且nmap运用自带的脚本&#xff0c;还能完成漏洞检测&#xff0c;同时支…

nmap常见使用方法

基础使用&#xff1a; 1.nmap ip 探测目标ip1-10000范围内所有开放端口 比如&#xff1a;扫描192.168.91.1 可以看见&#xff0c;已经扫描出目标IP对应的一些信息了 2.nmap -vv ip 简单扫描&#xff0c;输出详细结果&#xff08;一般没什么用&#xff09; nmap -p port ip …

Nmap 基本使用方法

一、下载工具包 进入官网下载安装包Download the Free Nmap Security Scanner for Linux/Mac/Windows 二、安装zenmap 工具 点击“下一步”安装完成。Zenmap 界面如下 三、Nmap使用 Nmap是主机扫描工具,他的图形化界面是Zenmap,分布式框架为Dnamp。 Nmap可以完成以下任务…

nmap 使用方法详细介绍

nmap的使用 前言nmap 作用Nmap使用教程nmap的基本输入&#xff1a;扫描参数&#xff1a;端口扫描&#xff1a;端口状态扫描&#xff1a;UDP扫描协议扫描 总结Nmap的基础知识Nmap的扫描技术Nmap的OS检测&#xff08;O&#xff09;Nmap的操作系统指纹识别技术&#xff1a; 前言 …

Nmap使用方法及常用命令学习

本文为学习笔记&#xff0c;仅限学习交流。不得利用、从事危害国家或人民安全、荣誉和利益等活动。 请参阅《中华人民共和国网络安全法》 7-30作业 —Nmap 练习 Nmap 是Network Mapper&#xff0c;中文为“网络映射器”。 Nmap 是一款开源的网络探测和安全审核的工具&#xff…

Nmap使用方法简析

NMAP 引子&#xff1a; Nmap&#xff0c; 是 Network Mapper 的缩写&#xff0c;由 Gordon Lyon 维护(更多关于 Mr. Lyon 的信息在这里: http://insecure.org/fyodor/) &#xff0c;并被世界各地许多的安全专业人员使用。 这个工具在 Linux 和 Windows 下都能使用&#xff0…

nmap使用方法详解

Nmap详解 Nmap&#xff08;网络映射器&#xff09;是一款开放源代码的网络探测和安全审核工具&#xff0c;它被设计用来快速扫描大型网络&#xff0c;包括主机探测与发现、开放的端口情况、操作系统与应用服务指纹识别、WAF识别及常见安全漏洞。 Nmap的特点&#xff1a; - 主机…

Nmap的使用方法总结

文章目录 Nmap的使用方法总结一&#xff1a;各种参数的使用1&#xff1a;ping扫描 —— nmap < 要扫描的目标ip地址>2&#xff1a;TCP SYN Ping扫描3&#xff1a;-PA TCP ACK Ping扫描4&#xff1a;半开扫描5&#xff1a;自定义端口扫描 nmap -P&#xff08;扫描范围&…

nmap使用方法

目录 第一、nmap使用 第一、nmap使用 1、nmap扫描一台服务器&#xff0c;默认扫描1000个最有可能开放的TCP端口。 2、-v显示详细信息 3、-p表示端口扫描。 扫描全部端口&#xff0c;查看开放了那些。 4、查看端口正在被那个进程使用 查看22端口正在被那个进程使用。 查看s…

Nmap使用教程图文教程(超详细)

kali的命令行中可以直接使用 nmap 命令&#xff0c;打开一个「终端」&#xff0c;输入 nmap 后回车&#xff0c;可以看到 nmap 的版本&#xff0c;证明 nmap 可用。 Nmap有四种基本功能&#xff1a;「端口扫描」、「主机探测」、「服务识别」和「系统识别」。 一、端口扫描 扫…

诗词——人间绝句

人生若只如初见&#xff0c;何事秋风悲画扇。 ——纳兰性德《木兰花令拟古决绝词谏友》 花自飘零水自流&#xff0c;一种相思&#xff0c;两处闲愁。 ——李清照《一剪梅红藕香残玉覃秋》 最是人间留不住&#xff0c;朱颜辞镜花辞树。 ——王国维《蝶恋花》 金风玉露一相逢&…