前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >shiro框架是什么_中国历史知识框架

shiro框架是什么_中国历史知识框架

作者头像
全栈程序员站长
发布2022-10-05 09:04:00
5180
发布2022-10-05 09:04:00
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

Shiro

1.权限管理概述

2.Shiro权限框架 2.1 概念 2.2 Apache Shiro 与Spring Security区别

3.Shiro认证 3.1 基于ini认证 3.2 自定义Realm –认证

4.Shiro授权 4.1 基于ini授权 4.2 自定义realm – 授权

5.项目集成shiro 认证-授权注意点 5.1 认证 5.2 授权 5.3 注解@RequiresPermissions() 5.4 标签式权限验证

6.Shiro加密

7.Shiro缓存

权限管理概述

RBAC(Role Based Access Control) :某个用户拥有什么角色,被允许做什么事情(权限)

用户登录—>分配角色—->(权限关联映射)—->鉴权(拥有什么什么权限)

熟悉框架流程

  • 概念 能做什么
  • 架构是怎样
  • 代码怎么实现
  • 项目运用

Shiro权限框架

  • 概念: Apache Shiro 是一个强大且易用的 Java 安全框架
  • 能做什么:Shiro可以帮我们完成 :认证授权、加密、会话管理、与 Web 集成、缓存等。
  • 架构是怎样的
在这里插入图片描述
在这里插入图片描述

主要认识:

  • Subject(用户):当前的操作用户 获取当前用户Subject currentUser = SecurityUtils.getSubject()
  • SecurityManager(安全管理器):Shiro的核心,负责与其他组件进行交互,实现 subject 委托的各种功能
  • Realms(数据源) :Realm会查找相关数据源,充当与安全管理间的桥梁,经过Realm找到数据源进行认证,授权等操作
  • Authenticator(认证器): 用于认证,从 Realm 数据源取得数据之后进行执行认证流程处理。
  • Authorizer(授权器):用户访问控制授权,决定用户是否拥有执行指定操作的权限。
  • SessionManager (会话管理器):支持会话管理
  • CacheManager (缓存管理器):用于缓存认证授权信息
  • Cryptography(加密组件):提供了加密解密的工具包

Apache Shiro 与Spring Security区别

代码语言:javascript
复制
Shiro::用于中小型项目比较常见,简单易上手,可以支持多种环境
       Shiro 可以不跟任何的框架或者容器绑定,可独立运行
Spring Security:一般多用于spring环境,中大型项目,更强大
                Spring Security 则必须要有Spring环境

Shiro认证

基于ini认证

代码语言:javascript
复制
1.新建项目 --导入依赖
           --新建 配置文件ini
    
2. shiro帮我们创建用户
    创建令牌 ,类比页面传入的账号密码
    密码错误--  IncorrectCredentialsException
    账号错误--  UnknownAccountException
    
   源码分析--
在这里插入图片描述
在这里插入图片描述
  • 导入依赖
代码语言:javascript
复制
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
<scope>provided</scope>
</dependency>
  • 编写ini,shiro默认支持的是ini配置的方式(只是演示) shiro-au.ini,真实项目使用xml
代码语言:javascript
复制
#用户的身份、凭据
[users]
zhangsan=555
xiaoluo=666
  • 使用 Shiro 相关的 API 完成身份认证
代码语言:javascript
复制
@Test
public void testLogin(){ 

//创建Shiro的安全管理器,是shiro的核心
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//加载shiro.ini配置,得到配置中的用户信息(账号+密码)
IniRealm iniRealm = new IniRealm("classpath:shiro-au.ini");
securityManager.setRealm(iniRealm);
//把安全管理器注入到当前的环境中
SecurityUtils.setSecurityManager(securityManager);
//无论有无登录都可以获取到subject主体对象,但是判断登录状态需要利用里面的属性来判断
Subject subject = SecurityUtils.getSubject();
System.out.println("认证状态:"+subject.isAuthenticated());
//创建令牌(携带登录用户的账号和密码)
UsernamePasswordToken token = new UsernamePasswordToken("xiaoluo","666");
//执行登录操作(将用户的和 ini 配置中的账号密码做匹配)
subject.login(token);
System.out.println("认证状态:"+subject.isAuthenticated());
//登出
//subject.logout();
//System.out.println("认证状态:"+subject.isAuthenticated());
}

自定义Realm–认证

模拟

代码语言:javascript
复制
@Getter
@Setter
public class Employee { 

private String username;
private String password;}

思路:

代码语言:javascript
复制
//继承 AuthorizingRealm
//参数的token ,subject进行登录匹配传入的token : UsernamePasswordToken
1.获取用户名
方式一:将token强转为UsernamePasswordToken-->getUsername()
方式二:通过token.getPrincipal()    
2.以用户名为条件,查询mysql数据库,得到用户对象(用户名/密码)
模拟从数据库查询的对象 ------->自己new一个
3.将用户对象封装成认证info对象返回
//存在两种可能
1.用户对象为null-----> return null
2.不为空 ---->封装数据 return new SimpleAuthenticationInfo(
有3个参数 
1.employee ,  //从数据库查询出来需要进行密码匹配的用户对象
2.employee.getPassword(),  //匹配对象密码
3.super.getName()  //指定realm的名称 ,可自定义
)

实现:

代码语言:javascript
复制
public class Realm extends AuthorizingRealm { 

//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 

//1.获取登录用户名
String username = (String) token.getPrincipal();
//2.以用户名为条件查询mysql数据库,得到用户对象
//模拟数据
Employee employee = new Employee();
employee.setUsername("xiaoluo");
employee.setPassword("123");
//封装成一个认证info对象
//判断用户是否为空
if (employee!=null){ 

return new SimpleAuthenticationInfo(
employee,
employee.getPassword(),
super.getName()
);
}
return null;
}
}
代码语言:javascript
复制
@Test
public void testLogin(){ 

//创建Shiro的安全管理器,是shiro的核心
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//自定义Realm,查出用户信息
Realm realm = new Realm();
securityManager.setRealm(realm);
//把安全管理器注入到当前的环境中
SecurityUtils.setSecurityManager(securityManager);
//无论有无登录都可以获取到subject主体对象,但是判断登录状态需要利用里面的属性来判断
Subject subject = SecurityUtils.getSubject();
System.out.println("认证状态:"+subject.isAuthenticated());
//创建令牌(携带登录用户的账号和密码)
UsernamePasswordToken token = new UsernamePasswordToken("xiaoluo","123");
//执行登录操作(将用户的和 ini 配置中的账号密码做匹配)
subject.login(token);
System.out.println("认证状态:"+subject.isAuthenticated());
//登出
//subject.logout();
//System.out.println("认证状态:"+subject.isAuthenticated());
}

Shiro授权

基于ini授权

  • 登录
  • 分配
  • 鉴权
代码语言:javascript
复制
    权限表达式   资源:操作
admin=*:*  //超级管理员
emp=employee:*
代码语言:javascript
复制
//判断是否有某个角色
subject.hasRole("role");
//用户拥有所有指定角色返回true
subject.hasAllRoles(Arrays.aList("role1","role2"));
//判断用户是否有指定角色,将结果返回,封装到boolean数组中
boolean[] booleans=subject.hasRoles(Arrays.aList("role1","role2"));                        
//check开头的是没有返回值,当没有权限时就会抛出异常
subject.checkRole("role"); 
//判断用户是否有某个权限
subject.isPermitted("权限表达式")
boolean[] booleans=subject.isPermitted("权限表达式1","权限表达式2")
在这里插入图片描述
在这里插入图片描述

自定义realm — 授权

思路:

代码语言:javascript
复制
1.获取当前登录用户的id/name
//获取当前登录用户对象 ,登录传过来的第一个参数
方式一 :principals.getPrimaryPrincipal();
方式二:SecurityUtils.getSubject().getPrincipal();
2.以用户id作为条件查询mysql数据,查询该用户拥有角色/权限
//假装查数据
//List<String> roles= roleService.queryByEmployee(Employee.getId());
//List<String> //List<String> roles= permissionService.queryByEmployee(Employee.getId());
= permissionService.queryByEmployee(Employee.getId());
3.将角色与权限封装到授权info对象中 
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles) //添加角色
info.addStringPermission(permission);//添加权限 

实现:

代码语言:javascript
复制
 //授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 

//获取当前用户对象
Employee employee = (Employee)principalCollection.getPrimaryPrincipal();
//以用户id查询数据库,判断该角色/用户是否拥有权限 模拟
List<String> roles= Arrays.asList("seller");
List<String> permissions= Arrays.asList("customer:list","customer:save");
//封装到info对象
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles);
info.addStringPermissions(permissions);
return info;
}
代码语言:javascript
复制
public class ShiroDemo { 

@Test
public void testLogin(){ 

//创建Shiro的安全管理器,是shiro的核心
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//加载shiro.ini配置,得到配置中的用户信息(账号+密码)
IniRealm iniRealm = new IniRealm("classpath:shiro-author.ini");
//自定义Realm,查出用户信息
Realm realm = new Realm();
securityManager.setRealm(realm);
//把安全管理器注入到当前的环境中
SecurityUtils.setSecurityManager(securityManager);
//无论有无登录都可以获取到subject主体对象,但是判断登录状态需要利用里面的属性来判断
Subject subject = SecurityUtils.getSubject();
System.out.println("认证状态:"+subject.isAuthenticated());
//创建令牌(携带登录用户的账号和密码)
UsernamePasswordToken token = new UsernamePasswordToken("xiaoluo","12");
//执行登录操作(将用户的和 ini 配置中的账号密码做匹配)
subject.login(token);
System.out.println("认证状态:"+subject.isAuthenticated());
//登出
//subject.logout();
//System.out.println("认证状态:"+subject.isAuthenticated());
//判断用户是否有某个角色
System.out.println("hr:"+subject.hasRole("hr"));
System.out.println("seller:"+subject.hasRole("seller"));
//是否同时拥有多个角色
System.out.println("是否同时拥有role1和role2:"+subject.hasAllRoles(Arrays.asList("hr", "seller")));
boolean[] booleans = subject.hasRoles(Arrays.asList("hr", "seller"));
//System.out.println(booleans);
//check开头的是没有返回值的,当没有权限时就会抛出异常
subject.checkRole("seller");
//判断用户是否有某个权限
System.out.println("user:delete:"+subject.isPermitted("user:delete"));
subject.checkPermission("customer:list");
}
}
代码语言:javascript
复制
	//如果用户是超级管理员 
//设置超级管理员角色
info.addRole("admin")
//设置超级管理员权限
info.addStringPermission("*:*");

项目集成shiro 认证-授权注意点

认证

代码语言:javascript
复制
1.添加对应依赖
2.配置代理过滤器
为什么不用配置拦截器?
Shiro是选择使用filter过滤器来进行拦截的,因为Shiro不依赖Spring容器,所以当没有springmvc时意味着不能用拦截器,但过滤器则不同,只要是web项目都可以使用
3.创建shiro.xml
4.配置shiro过滤器
<!--引用指定的安全管理器-->
<!--shiro默认的登录地址是/login.jsp 现在要指定我们自己的登录页面地址-->
<!--路径对应的规则-->
5.配置安全管理器  DefaultWebSecurityManager
6.修改LoginController
7.配置自定义Realm
8.将自定义Realm交给容器管理
shiro中的过滤器

过滤器的名称

Java 类

anon

org.apache.shiro.web. lter.authc.AnonymousFilter

authc

org.apache.shiro.web. lter.authc.FormAuthenticationFilter

authcBasic

org.apache.shiro.web. lter.authc.BasicHttpAuthenticationFilter

roles

org.apache.shiro.web. lter.authz.RolesAuthorizationFilter

perms

org.apache.shiro.web. lter.authz.PermissionsAuthorizationFilter

user

org.apache.shiro.web. lter.authc.UserFilter

logout

org.apache.shiro.web. lter.authc.LogoutFilter

port

org.apache.shiro.web. lter.authz.PortFilter

rest

org.apache.shiro.web. lter.authz.HttpMethodPermissionFilter

ssl

org.apache.shiro.web. lter.authz.SslFilter

  • anon: 匿名处理过滤器,即不需要登录即可访问;一般用于静态资源过滤;/static/**=anon
  • authc: 表示需要认证(登录)才能使用;(放最后) /**=authc
  • logout: 注销过滤器 /logout=logout
  • roles: 角色授权过滤器,验证用户是否拥有资源角色; /employee/input=perms["user:update"]

授权

  • 没有权限的异常 :org.apache.shiro.authz.UnauthorizedException
代码语言:javascript
复制
shiro注解鉴权操作方式:
类比RBAC:
1.自定义权限注解
2.将注解贴在请求映射方法上面
3.将注解标注的权限表达式加载到数据库中
4.将这些表达式根据用户角色进行权限分配
5.当用户登录之后,访问某个请求映射方法时,先经过权限拦截器,进行鉴权操作
1.获取当前登录用户权限表达式集合
2.获取当前请求映射方法头顶上权限表达式
3.判断用户权限表达式集合中是否包含该表达式

Shiro 权限验证三种方式

  • 编程式
  • 注解式
  • 页面标签式
代码语言:javascript
复制
1.编程式
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("hr")) { 

//有权限
} else { 

//无权限
}
--------------------------------------
2.注解式
@RequiresRoles("admin") 
@RequiresPermissions("user:create") 
public void hello() { 

//有权限
}
----------------------------------------
3.页面标签式
<@shiro.hasPermission name="employee:list">
<!-- 有权限 -->
</@shiro.hasRole>

授权步骤

代码语言:javascript
复制
1.贴注解
2.开启 Shiro 注解扫描器
3.查询数据库真实数据 自定义realm    
注解@RequiresPermissions()
  • value属性: 这个属性是一个数组
  • Logical.AND: 必须同时拥有value配置所有权限才允许访问
  • Logical.OR:只需要拥有value配置所有权限中一个即可允许访问
代码语言:javascript
复制
约定:权限表达式,第一值权限表达式,第二值为权限名称
@RequiresPermissions(value={ 
"employee:list","员工列表"},logical=Logical.OR)
逻辑为OR,value满足其中一个条件成立
标签式权限验证

拓展FreeMarker标签

代码语言:javascript
复制
默认的freemarker是不支持shiro标签,所以需要做功能拓展
----------------   
public class ShiroFreeMarkerConfig extends FreeMarkerConfigurer { 

@Override
public void afterPropertiesSet() throws IOException, TemplateException { 

//继承之前的属性配置,这不能省
super.afterPropertiesSet();
Configuration cfg = this.getConfiguration();
cfg.setSharedVariable("shiro", new ShiroTags());//注册shiro 标签
}
}  
--------------------------让之前的配置文件
中的FreeMarkerConfigurer修改为自定义的ShiroFreeMarkerConfig类
<!-- 注册 FreeMarker 配置类 -->
<bean class="cn.k.shiro.ShiroFreeMarkerConfig">
<!-- 配置 FreeMarker 的文件编码 -->
<property name="defaultEncoding" value="UTF-8" />
<!-- 配置 FreeMarker 寻找模板的路径 -->
<property name="templateLoaderPath" value="/WEB-INF/views/" />
<property name="freemarkerSettings">
<props>
<!-- 兼容模式 ,配了后不需要另外处理空值问题,时间格式除外 -->
<prop key="classic_compatible">true</prop>
</props>
</property>
</bean>
使用shiro标签
  • authenticated 标签:已认证通过的用户。
代码语言:javascript
复制
<@shiro.authenticated> </@shiro.authenticated>
  • notAuthenticated 标签:未认证通过的用户。
代码语言:javascript
复制
<@shiro.notAuthenticated></@shiro.notAuthenticated>
  • principal 标签 :输出当前用户信息,通常为登录帐号信息
代码语言:javascript
复制
<@shiro.principal property="name" /> //对应name属性
  • hasRole 标签:验证当前用户是否拥有该角色
代码语言:javascript
复制
<@shiro.hasRole name="admin">我是管理员</@shiro.hasRole>
  • hasAnyRoles 标签:验证当前用户是否拥有这些角色中的任何一个,角色之间逗号分隔
代码语言:javascript
复制
<@shiro.hasAnyRoles name="admin,user,hr">Hello admin</@shiro.hasAnyRoles>
  • hasPermission 标签:验证当前用户是否拥有该权限
代码语言:javascript
复制
<@shiro.hasPermission name="department:delete">删除</@shiro.hasPermission>

Shiro加密

MD5

代码语言:javascript
复制
//参数1 :原文,参数2:盐 ,参数3:散列次数(加密次数)
Md5Hash hash=new Md5Hash("1","kent",3);

盐一般要求是固定长度的字符串,且每个用户的盐不同。

代码语言:javascript
复制
一般盐的选择的是用户的唯一数据(账号名等),盐是要求不能改变的,不然下次加密结果就对应不上了

Shiro缓存

当我们登录时,授权信息是要从数据库中查询的,如果每次刷新刷新都需要获取你到底有没有权限,对性能影响不好,用户登录后,授权信息一般很少改动,所以,我们可以将第一次授权后,将信息存在缓存中,下次直接再缓存中获取,就很好的避免了多次访问数据库

Shiro没有实现自己的缓存机制,只提供了支持缓存的API接口,这里使用的是EhCache

代码语言:javascript
复制
mybatis 一级  二级缓存------百度(ing)补充

集成EhCache

代码语言:javascript
复制
第三方EhCache
1.配置缓存管理器并引用缓存管理器
<!--安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--注册自定义数据源-->
<property name="realm" ref="employeeRealm"/>
<!--注册缓存管理器-->
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> 
<!-- 设置配置文件 -->
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
----------------------------------------
2.添加缓存配置文件  shiro-ehcache.xml
<ehcache>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
配置缓存文件属性说明
  • maxElementsInMemory: 缓存对象最大个数。
  • eternal:对象是否永久有效 ,一般为false
  • timeToIdleSeconds: 对象空闲时间
  • timeToLiveSeconds:对象存活时间
  • memoryStoreEvictionPolicy:当达到 maxElementsInMemory 限制时,Ehcache 将会根据指定的策略去清理内存。
  • LFU(较少使用,意思是一直以来最少被使用的,缓存的元素有一个hit 属性(命中率),hit 值最小的将会被清出缓存)默认
拓展 统一全局异常

@ControllerAdvice 控制器功能增强注解

代码语言:javascript
复制
1.在进入请求映射方法之前做功能增强,经典用法:date日期格式化
2.在进入请求映射方法之后做功能增强,经典用法:统一异常处理 
3.处理异常的方法,方法需要贴ExceptionHandler注解

配置文件

配置代理过滤器

代码语言:javascript
复制
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

配置shiro.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--引入自定义Realm-->
<bean id="employeeRealm" class="cn.k.shiro.EmployeeRealm">
</bean>
<!--配置安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="employeeRealm"/>
<!--注册缓存管理器-->
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!--配置shiro过滤器-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--引用指定的安全管理器-->
<property name="securityManager" ref="securityManager"/>
<!--shiro默认的登录地址是/login.jsp 现在要指定我们自己的登录页面地址-->
<property name="loginUrl" value="/login.html"/>
<!--路径对应的规则-->
<property name="filterChainDefinitions">
<value>
/userLogin=anon
/css/**=anon
/js/**=anon
/img/**=anon
/upload/**=anon
/userLogout=logout
/**=authc
</value>
</property>
</bean>
<!--开启 Shiro 注解扫描器-->
<!-- <aop:config/> 会扫描配置文件中的所有advisor,并为其创建代理 -->
<aop:config/>
<!-- Pointcut advisor通知器, 会匹配所有加了shiro权限注解的方法 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 设置配置文件 -->
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
</beans>

关联mvc.xml

代码语言:javascript
复制
<import resource="classpath:shiro.xml"/>

loginController

代码语言:javascript
复制
@RequestMapping("/userLogin")
@ResponseBody
public JsonResult login(String username, String password){ 

try { 

UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);
return new JsonResult();
} catch (UnknownAccountException e) { 

return new JsonResult(false, "账号不存在");
} catch (IncorrectCredentialsException e) { 

return new JsonResult(false, "密码错误");
} catch (Exception e) { 

e.printStackTrace();
return new JsonResult(false, "登录异常,请联系管理员");
}
}

关联mvc.xml

代码语言:javascript
复制
<import resource="classpath:shiro.xml"/>

loginController

代码语言:javascript
复制
@RequestMapping("/userLogin")
@ResponseBody
public JsonResult login(String username, String password){ 

try { 

UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);
return new JsonResult();
} catch (UnknownAccountException e) { 

return new JsonResult(false, "账号不存在");
} catch (IncorrectCredentialsException e) { 

return new JsonResult(false, "密码错误");
} catch (Exception e) { 

e.printStackTrace();
return new JsonResult(false, "登录异常,请联系管理员");
}
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月8日 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Shiro
    • 权限管理概述
      • 熟悉框架流程
    • Shiro权限框架
      • Apache Shiro 与Spring Security区别
    • Shiro认证
      • 基于ini认证
      • 自定义Realm–认证
    • Shiro授权
      • 基于ini授权
      • 自定义realm — 授权
    • 项目集成shiro 认证-授权注意点
      • 认证
      • 授权
    • Shiro加密
      • MD5
    • Shiro缓存
      • 集成EhCache
    • 配置文件
      • 配置代理过滤器
      • 配置shiro.xml
      • 关联mvc.xml
      • loginController
      • 关联mvc.xml
      • loginController
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档