文章目录
- 一、 springboot实现普通登录
- 1 添加依赖
- 2 编写配置文件
- 3 新建实体类和mapper
- 4 编写业务层代码
- 5 编写控制器
- 6 编写启动类
- 7 编写登录页面和主页面
- 二、 springboot整合shiro实现登录认证和凭证匹配
- 1 添加依赖
- 2 自定义Realm
- 3 编写配置
- 4 userService新增单元方法:使用shiro认证
- 5 凭证匹配器
- 5.1 修改ShiroConfig
- 5.2 修改MyRealm
- 三、 remember me实现---shiro已经集成
- 1 修改application.yml-----增加shiro的loginUrl地址
- 2 增加记住我的按钮
- 3 修改Controller
- 4 修改ShiroConfig
- 四、 配置退出
- 1 修改配置类
- 2 修改主页面
- 五、 授权
- 1 简介
- 2 Thymeleaf整合shiro
- 2.1 添加依赖
- 2.2 修改配置类(负责解析thymeleaf中shiro的相关属性)
- 2.3 修改Realm
- 2.4 修改main.html
- 3 使用注解判断方法是否具有权限执行
- 3.1 修改main.html
- 3.2 修改UserController类
- 3.3 新建依赖处理类
- 六 EHCache
- 1 ehcache简介
- 2 EHCache API演示
- 2.1 添加依赖
- 2.2 新建配置文件
- 七 Shiro和EhCache整合
- 1 添加依赖
- 2 编写ehcache缓存配置
- 3 修改配置文件
- 八 Shiro中Session对象获取
一、 springboot实现普通登录
1 添加依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>02_shiro_springboot_login</artifactId>
<version>1.0-SNAPSHOT</version>
<!--配置继承-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.10.RELEASE</version>
</parent>
<!--配置依赖-->
<dependencies>
<!--配置web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--配置mybatis启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--配置mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!--配置Thrmeleaf启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</project>
2 编写配置文件
新建application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
url: jdbc:mysql://localhost:3306/springboot-login
password: 1234
##配置mapper的xml文件的路径
mybatis:
mapper-locations: classpath:mybatis/*.xml
3 新建实体类和mapper
新建com.bjsxt.pojo.User
public class User { private Long id; private String username; private String pwd; // 省略getter和setter // 省略构造方法 }
新建com.bjsxt.mapper.UserMapper
package com.bjsxt.mapper; public interface UserMapper { //根据用户名查询用户信息 @Select("select * from t_user where uname=#{uname}") User selUserInfoMapper(@Param("uname") String uname); }
4 编写业务层代码
新建com.bjsxt.service.UserService及实现类
public interface UserService {
//用户登录
User selUserInfoService(String uname);
}
@Service
public class UserServiceImpl implements UserService {
//声明mapper属性
@Autowired
private UserMapper userMapper;
//用户登录
@Override
public User selUserInfoService(String uname) {
return userMapper.selUserInfoMapper(uname);
}
}
5 编写控制器
新建com.bjsxt.controller.UserController
package com.bjsxt.controller;
@Controller
public class UserController {
//声明service属性
@Autowired
private UserService userService;
//声明单元方法:登录认证
@RequestMapping("userLogin")
public String userLogin(String uname,String pwd){
//1.根据用户名获取用户信息
User user=userService.selUserInfoService(uname);
//2.判断用户名是否合法
if(user!=null){
//3.校验密码
if(user.getPwd().equals(pwd)){
//认证成功
return "main";
}
}
return "error";
}
//声明公共单元方法完成页面的内部转发
@RequestMapping("{uri}")
public String getPage(@PathVariable String uri){
return uri;
}
}
6 编写启动类
新建com.bjsxt.ShiroApplication
package com.bjsxt;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.bjsxt.mapper")
public class ShiroApplication {
public static void main(String[] args) {
SpringApplication.run(ShiroApplication.class,args);
}
}
7 编写登录页面和主页面
新建templates/login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>SpringBoot整合Shiro登录案例</h3>
<hr>
<!--创建登录页面-->
<form action="userLogin" method="post">
用户名: <input type="text" name="uname" value=""><br>
密码: <input type="password" name="pwd" value=""><br>
<input type="submit" value="登录">
</form>
</body>
</html>
新建templates/main.html。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
我是主页面
</body>
</html>
二、 springboot整合shiro实现登录认证和凭证匹配
1 添加依赖
<dependencies>
<!-- 注释掉web启动器是因为shiro-spring-boot-web-starter依赖了spring-boot-starter-web -->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>-->
<!--配置shiro的启动器-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.2</version>
</dependency>
</dependencies>
2 自定义Realm
新建com.bjsxt.shiro.MyRealm编写认证逻辑
package com.bjsxt.shiro;
//配置为Bean对象
@Component
public class MyRealm extends AuthorizingRealm {
//声明业务层属性
@Autowired
private UserService userService;
//自定义授权策略
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
//自定义认证策略
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//声明认证代码
//1.获取用户传递的用户名信息
Object principal = token.getPrincipal();
//2.根据用户名获取数据库中的用户信息
User user = userService.selUserInfoService((String) principal);
//3.认证
if(user!=null){//用户名是正确的
//4.认证密码
AuthenticationInfo info= new SimpleAuthenticationInfo(principal,user.getPwd(), user.getUname());
return info;
}
return null;
}
}
3 编写配置
新建com.bjsxt.config.ShiroConfig,编写配置
package com.bjsxt.config;
@Configuration
public class ShiroConfig {
//声明MyRealm属性
@Autowired
private MyRealm myRealm;
//声明bean方法
@Bean
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(myRealm);
return defaultWebSecurityManager;
}
4 userService新增单元方法:使用shiro认证
package com.bjsxt.controller;
@Controller
public class UserController {
//声明单元方法:使用shiro认证
@RequestMapping("userLogin2")
public String userLogin2(String uname,String pwd){
//1.获取subject对象
Subject subject = SecurityUtils.getSubject();
//2.认证
//创建认证对象存储认证信息
AuthenticationToken token= new UsernamePasswordToken(uname,pwd);
try{
subject.login(token);
return "redirect:main";
}catch(Exception e){
e.printStackTrace();
}
return "redirect:login";
}
//声明公共单元方法完成页面的内部转发
@RequestMapping("{uri}")
public String getPage(@PathVariable String uri){
return uri;
}
}
此时登录出现问题:访问login时报错,错误说找不到login.jsp,应该找的是login.html
解决:在ShiroConfig配置类自定义shiro过滤器参数bean
package com.bjsxt.config;
@Configuration
public class ShiroConfig {
//自定义shiro过滤器参数bean
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/login", "anon");
definition.addPathDefinition("/userLogin", "anon");
definition.addPathDefinition("/main", "anon");
definition.addPathDefinition("/**", "user");
return definition;
}
}
将
<form action="userLogin" method="post">
改为<form action="userLogin2" method="post">
<body>
<h3>SpringBoot整合Shiro登录案例</h3>
<hr>
<!--创建登录页面-->
<form action="userLogin2" method="post">
用户名: <input type="text" name="uname" value=""><br>
密码: <input type="password" name="pwd" value=""><br>
<input type="submit" value="登录">
</form>
</body>
启动测试
5 凭证匹配器
首先将数据库中用户张三的密码改为:6bdae6366c1e46d541eb0ca9547d974c
5.1 修改ShiroConfig
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager defaultWebSecurityManager= new DefaultWebSecurityManager();
//创建凭证匹配器
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(2);
myRealm.setCredentialsMatcher(matcher);
//将自定义的认证策略对象注入到SecurityManager
defaultWebSecurityManager.setRealm(myRealm);
return defaultWebSecurityManager;
}
5.2 修改MyRealm
修改MyRealm中doGetAuthenticationInfo方法。
//自定义认证策略
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//声明认证代码
//1.获取用户传递的用户名信息
Object principal = token.getPrincipal();
//2.根据用户名获取数据库中的用户信息
User user = userService.selUserInfoService((String) principal);
//3.认证
if(user!=null){//用户名是正确的
//4.认证密码
AuthenticationInfo info= new SimpleAuthenticationInfo(principal,user.getPwd(), ByteSource.Util.bytes(user.getUid()+""),user.getUname());
return info;
}
return null;
}
三、 remember me实现—shiro已经集成
1 修改application.yml-----增加shiro的loginUrl地址
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
url: jdbc:mysql://localhost:3306/springboot-login
password: 1234
##配置mapper的xml文件的路径
mybatis:
mapper-locations: classpath:mybatis/*.xml
shiro:
##当用户访问某个需要登录的功能时,但是被shiro内置的过滤器拦截后,判断本次请求
##没有登录,而是直接访问的,则重定向到loginUrl的路径资源响应给用户
loginUrl: /login
2 增加记住我的按钮
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>SpringBoot整合Shiro登录案例</h3>
<hr>
<!--创建登录页面-->
<form action="userLogin2" method="post">
用户名: <input type="text" name="uname" value=""><br>
密码: <input type="password" name="pwd" value=""><br>
<input type="submit" value="登录">
<input type="checkbox" name="rememberme" value="true">记住俺
</form>
</body>
</html>
3 修改Controller
@RequestMapping("userLogin2")
public String userLogin2(String uname,String pwd,@RequestParam(defaultValue = "false") Boolean rememberme){
//1.获取subject对象
Subject subject = SecurityUtils.getSubject();
//2.认证
//创建认证对象存储认证信息
AuthenticationToken token= new UsernamePasswordToken(uname,pwd,rememberme);
try{
subject.login(token);
return "redirect:main";
}catch(Exception e){
e.printStackTrace();
}
return "redirect:login";
}
4 修改ShiroConfig
@Bean
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
//创建凭证匹配器
HashedCredentialsMatcher matcher=new HashedCredentialsMatcher();
//设置匹配器的加密算法
matcher.setHashAlgorithmName("md5");
//设置匹配器的迭代加密次数
matcher.setHashIterations(2);
//将匹配器注入到自定义的认证策略对象中
myRealm.setCredentialsMatcher(matcher);
//将自定义的认证策略对象注入到SecurityManager
defaultWebSecurityManager.setRealm(myRealm);
//将CookieRememberMeManager对象注入到SecurityManager,开启了rememberme功能
defaultWebSecurityManager.setCacheManager(ehCacheManager());
return defaultWebSecurityManager;
}
//设置Cookie的信息
public SimpleCookie rememberMeCookie(){
SimpleCookie simpleCookie=new SimpleCookie("rememberMe");
//设置有效路径
simpleCookie.setPath("/");
//设置声明周期
simpleCookie.setMaxAge(30*24*60*60);
//返回设置的cookie
return simpleCookie;
}
//创建rememberMeManager对象
public CookieRememberMeManager rememberMeManager(){
//创建CookieRememberMeManager对象
CookieRememberMeManager cookieRememberMeManager=new CookieRememberMeManager();
//注入Cookie对象
cookieRememberMeManager.setCookie(rememberMeCookie());
//设置密钥
cookieRememberMeManager.setCipherKey(Base64.decode("MTIzNDU2Nzg="));
//返回
return cookieRememberMeManager;
}
//自定义shiro过滤器参数bean----`definition.addPathDefinition("/**", "user");`
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/login", "anon");
definition.addPathDefinition("/userLogin2", "anon");
//开启shiro内置的退出过滤器,完成退出功能
definition.addPathDefinition("/logout", "logout");
//definition.addPathDefinition("/main", "anon");
definition.addPathDefinition("/**", "user");
return definition;
}
四、 配置退出
1 修改配置类
修改ShiroConfig类,添加logout filter 对应的url。
definition.addPathDefinition("/logout", "logout");
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", "anon");
definition.addPathDefinition("/logout", "logout");
definition.addPathDefinition("/**", "authc");
return definition;
}
2 修改主页面
在index.html页面中添加超链接。跳转到/logout后会由shiro内置filter进行拦截。
<body>
index.html
<a href="/logout">退出</a>
</body>
五、 授权
1 简介
授权就是判断认证用户是否具有指定角色或指定权限。
Shiro可以和JSP整合也可以和Thymeleaf整合,我们讲解SpringBoot的视图技术Thymeleaf整合Shiro。
只要是授权就执行Realm的doGetAuthorizationInfo进行判断,而触发doGetAuthorizationInfo的方式,常用的就两种:
(1)在页面中通过shiro:xxxx 属性进行判断
(2)在java代码中通过注解@RequiresXXX
thymeleaf中常用属性
需要在html页面中添加属性
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
1.1 shiro:user=””
认证通过或已记住的用户。
1.2 shiro:authenticated=””
认证通过的用户。不包含记住的用户。
1.3 shiro:principal
输出认证用户信息。shiro:principal/
1.4 shiro:hasRole=“admin”
判断是否具有指定角色。
1.5 shiro:lacksRole=“admin”
判断是否不是没有指定角色。
1.6 shiro:hasAllRoles=“role1,role2”
判断指定角色用户是否都具有。
1.7 shiro:hasAnyRoles=“role1,role2”
只要用户具有其中一个角色就表示判断通过。
1.8 shiro:hasPermission=“userInfo:add”
是否具有指定权限。
1.9 shiro:lacksPermission=“userInfo:del”
是否不具有指定权限
1.10 shiro:hasAllPermissions=“userInfo:view, userInfo:add”
是否全具有指定权限。
1.11 shiro:hasAnyPermissions=“userInfo:view, userInfo:del”
只要有其中任何一个权限即可。
2 Thymeleaf整合shiro
2.1 添加依赖
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2.2 修改配置类(负责解析thymeleaf中shiro的相关属性)
//创建解析Thymeleaf中的shiro属性的对象,由SpringBoot项目底层自动调用
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
2.3 修改Realm
绑定用户具有的角色和权限,相关数据应该是从数据库中取出。
//自定义授权策略
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//1.从数据库中获取用户的权限信息
//2.将权限信息存储到shiro授权对象中
System.out.println("我是授权认证方法,我被执行了");
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addRole("role1");
info.addRole("role2");
info.addStringPermission("user:insert");
info.addStringPermission("user:update");
info.addStringPermission("sys:*");
return info;
}
2.4 修改main.html
访问页面后会发现“有角色”不显示,“有权限”显示。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
我是主页面
<a href="/logout">退出</a>
<hr>
<span shiro:hasRole="role3">有角色</span><br>
<span shiro:user="">shiro:user=””认证通过或已记住的用户</span><br>
<span shiro:authenticated="">shiro:authenticated=””认证通过的用户。不包含记住的用户。</span><br>
<hr>
<a href="/demo">测试后台逻辑代码的授权</a>
</body>
</html>
3 使用注解判断方法是否具有权限执行
方法:可以用控制器方法,也可以是业务方法。常在控制器方法上添加注解进行判断。
常用注解:
(1)@RequiresPermissions("") 必须具有指定权限
(2)@RequiresAuthentication 必须已经认证
(3)@RequiresRoles("") 必须具有指定角色
(4)@RequiresUser 必须是已认证或记住用户
(5)@RequiresGuest 必须是访客
3.1 修改main.html
添加下面内容
<a href="/isPermission">跳转到判断权限的控制器</a>
3.2 修改UserController类
@RequestMapping("/isPermission")
@ResponseBody
@RequiresPermissions("abc:jqk")
public String isPermission(){
return "OK";
}
当用户登录成后,点击超链接“跳转到判断权限的”超链接会出现500错误页面信息。
3.3 新建依赖处理类
新建com.bjsxt.controller.NoPermissionException
@ControllerAdvice
public class NoPermissionException {
@ResponseBody
@ExceptionHandler(UnauthorizedException.class)
public String handleShiroException(Exception ex) {
return "无权限";
}
@ResponseBody
@ExceptionHandler(AuthorizationException.class)
public String AuthorizationException(Exception ex) {
return "权限认证失败";
}
}
六 EHCache
1 ehcache简介
EHCache是sourceforge的开源缓存项目,现已经具有独立官网,网址:(http://www.ehcache.org)。其本身是纯JAVA实现的,所以可以和绝大多数Java项目无缝整合,例如:Hibernate的缓存就是基于EHCache实现的。
EHCache支持内存和磁盘缓存,默认是存储在内存中的,当内存不够时允许把缓存数据同步到磁盘中,所以不需要担心内存不够问题。
EHCache支持基于Filter的Cache实现,同时也支持Gzip压缩算法提高响应速度。
2 EHCache API演示
2.1 添加依赖
从3.0版本开始groupid为org.ehcache
<dependencies>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.6.11</version>
</dependency>
</dependencies>
2.2 新建配置文件
在src/main/resources中新建ehcache.xml。
属性含义:
maxElementsInMemory:缓存中允许创建的最大对象数。
eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
timeToIdleSeconds:缓存数据的钝化时间,取值0表示无限长。
timeToLiveSeconds:缓存数据的生存时间,取值0表示无限长。
overflowToDisk:内存不足时,是否启用磁盘缓存。
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir/ehcache"/>
<!-- 默认缓存 -->
<defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!-- helloworld缓存 -->
<cache name="HelloWorldCache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="5"
timeToLiveSeconds="5"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
七 Shiro和EhCache整合
Shiro支持很多第三方缓存工具。官方提供了shiro-ehcache,实现了把EHCache当做Shiro的缓存工具的解决方案。其中最好用的一个功能是就是缓存认证执行的Realm方法,减少对数据库的访问。
1 添加依赖
添加shiro-ehcache依赖。
commons-io主要是为了使用里面的工具类。本质和当前整合功能没有关系。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2 编写ehcache缓存配置
在resources下新建ehcache/ehcache-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="ehcache" updateCheck="false">
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir"/>
<!-- 默认缓存 -->
<defaultCache
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false">
</defaultCache>
<!-- 登录记录缓存 锁定10分钟 -->
<cache name="loginRecordCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
</ehcache>
3 修改配置文件
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");
hashedCredentialsMatcher.setHashIterations(2);
myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
manager.setRealm(myRealm);
manager.setRememberMeManager(rememberMeManager());
manager.setCacheManager(getEhCacheManager());
return manager;
}
@Bean
public EhCacheManager ehCacheManager(){
EhCacheManager ehCacheManager = new EhCacheManager();
InputStream is = null;
try {
is = ResourceUtils.getInputStreamForPath("classpath:ehcache/ehcache-shiro.xml");
} catch (IOException e) {
e.printStackTrace();
}
net.sf.ehcache.CacheManager cacheManager = new net.sf.ehcache.CacheManager(is);
ehCacheManager.setCacheManager(cacheManager);
return ehCacheManager;
}
八 Shiro中Session对象获取
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute("key","value");