这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
思维导图
写的不全,写了大概
Shiro简介
Apache Shiro是一个强大的并且简单使用的java权限框架.主要应用认证(Authentication),授权(Authorization),cryptography(加密),和Session Manager.Shiro具有简单易懂的API,使用Shiro可以快速并且简单的应用到任何应用中,无论是从最小的移动app到最大的企业级web应用都可以使用.
核心功能
在Shiro官网首页上占用了很大的篇幅说明了Shiro的核心功能。
Authentication 认证。如用户的登录。
Authorization 授权。用户是否有权限访问指定URL等。
Cryptography 密码学。如密码的加密。
Session Management Session 管理。
Web Integration Web集成。Shiro不依赖于容器。
参考文献:shiro.apache.org/introductio…
架构
以下是个人理解:
Subject(主体):用户交互信息
Authenticator(认证器):认证器,用户认证
Authorizer(授权器):权限和角色的管理
SessionManager: HttpSession对象 由shiro Session管理
Session DAO : 操作session内容
CacheManager:缓存管理,如用户凭证,角色,权限信息的管理
Realm:授权,身份验证,从数据库获取用户信息对 权限校验,身份校验,角色校验
Cryptography(密码学):对用户密码进行加密,提高安全性
架构详细信息可以参考:shiro.apache.org/architectur…
Shiro 的INI文件配置
INI英文名称(InitializationFile)
INI文件是Window系统配置文件的扩展名.
Shiro的全局配置文件就是.ini文件,ini中数据都是固定数据,后面会用数据库中数据
Shiro 的INI文件配置 分为四个部分:
-
[main] 配置类对象,或设置属性等操作.
-
[users] 定义用户,密码及用户可以具有的角色
-
[roles] 定于角色具有的权限
-
[urls] 过滤器配置
实际开发中很少使用,这个了解一下就好了
Shiro注解
@RequiresPermissions 必须具有指定权限 @RequiresAuthentication 必须已经认证 @RequiresRoles 必须具有指定角色
@RequiresUser 必须是已认证或记住用户 @RequiresGuest 必须是访客
SpringBoot 整合 shiro
实现流程:
- 1.搭建Manve项目
- 2.导入依赖
- 3.编写代码
- 4.编写配置
这里就不演示了,提供依赖供参考
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.13.RELEASE</version>
</parent>
<dependencies>
<!--shiro集成了tomcat-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.2</version>
</dependency>
<!--springBoot 整合thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--shiro 整合 thymeleaf 方便页使用权限验证-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!--ehcache 做缓存-->
<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>
<!--mybatis的启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--数据库的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
配置文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/shiro?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: root
shiro:
loginUrl: /login #用户没有登录跳转路径
server:
port: 80
MD5 加密技术
public class TestMD5 {
public static void main(String[] args) {
Md5Hash md5Hash = new Md5Hash("test");
System.out.println(md5Hash.toHex());
/*加盐: 在密码中混入与密码不相干字符,提高密码解密难度*/
Md5Hash md5Hash2 = new Md5Hash("test", "abcd");
System.out.println(md5Hash2.toHex());
/*迭代次数:加密次数*/
Md5Hash md5Hash3 = new Md5Hash("test", "test", 2);
System.out.println(md5Hash3.toHex());
}
}
Shiro 整合 Thymeleaf 中的属性
shiro:user:认证通过或已记住的用户
shiro:authenticated :认证通过的用户。不包含记住的用户
shiro:principal :输出认证用户信息
shiro:hasRole :判断是否具有指定角色
shiro:lacksRole: 判断是否不具有指定角色
shiro:hasAllRoles:判断指定角色用户是否都具有
shiro:hasAnyRoles: 只要用户具有其中一个角色就表示判断通过。
shiro:hasPermission:是否具有指定权
shiro:lacksPermission:是否不具有指定权限
shiro:hasAllPermissions:是否全具有指定权限
shiro:hasAnyPermissions:只要有其中任何一个权限即可
示例
<a shiro:hasRole="role1" href="/demo1">角色认证</a>
<a shiro:hasPermission="sys:update" href="/demo2">权限认证</a>
Shiro过滤器规则
anon:不认证也可以访问。例如:/admin/**=anon /login=anon
authc:必须认证。 /**=authc ---所有的资源都认证
authcBasic:没有参数时表示httpBasic认证(客户端认证方式)。
logout:退出。
noSessionCreation:新增Filter,表示没有Session创建。
perms:判断是有具有指定权限。例如:/admin/user/**=perms[“per1”,”per2”]。必须同时具有给定权限才
可以访问。如果只有一个权限可以省略双引号。
port:限制端口。例如:/admin/**=port[8081]。只要请求不是8081端口就重新发送URL到8081端口。
rest:请求方式和权限的简便写法。例如:/admin/** =rest[user],相当于/admin/** = perms[user:方式],
方式是http请求的方式:post、get等。
roles:判断是否具有指定角色。/admin/**=roles[role1]
ssl:表示是安全的请求。协议为https
user:表示必须存在用户。
认证(登录实现)
实现流程:
- 1.获取用户身份信息,通过Subject获取
- 2.将用户身份信息,通过Authenticator(认证器) 验证
- 3.验证通过,允许登录,验证失败,跳回登录页面
编写控制类
/**
* 登录验证
*/
@RequestMapping("/doLogin")
public String login(String name, String pwd,HttpSession session) {
/*获取主体*/
Subject subject = SecurityUtils.getSubject();
/*存储用户身份信息*/
AuthenticationToken token = new UsernamePasswordToken(name, pwd);
try {
/*对用身份校验*/
subject.login(token);
System.out.println("登录成功");
session.setAttribute("user", token.getPrincipal().toString());
return "main";
} catch (UnknownAccountException e) {
System.out.println("账号不存在");
} catch (IncorrectCredentialsException e) {
System.out.println("密码错误");
} catch (AuthenticationException e) {
e.printStackTrace();
}
return "login";
}
自定义Realm,对用户名,密码验证
-
查询用户信息
-
自定义Realm ,对用户信息校验
编写一个类 继承AuthorizingRealm
@Component
public class MyRealm2 extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 自定义身份认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
/*获取身份*/
String principal = token.getPrincipal().toString();
/*身份验证*/
User login = userService.login(principal);
if (login!=null){
/*参数1:用户名,参数2:用户密码,参数3:盐值,参数4:真实名,没有什么用*/
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(principal, login.getPwd(),
ByteSource.Util.bytes(login.getSalt()), "test");
return info;
}
return null;
}
}
编写配置类
- 设置加密类型
- shiro 过滤器配置
@Configuration
public class Config2 {
@Autowired
private MyRealm2 myRealm2;
/*配置SecurityManager*/
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*设置加密*/
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");/*加密类型*/
matcher.setHashIterations(2);/*迭代次数*/
myRealm2.setCredentialsMatcher(matcher);
securityManager.setRealm(myRealm2); /*设置自定义realm*/
return securityManager;
}
/*配置过滤器*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/login", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/**", "authc"); /*配置登录成功后放行路径*/
definition.addPathDefinition("/**", "user");
return definition;
}
}
RememberMe(记住我)
- 前台传参 记住我
- 后台处理
- 配置RememberMe
修改登录控制单元方法
/**
* 登录验证
*/
@RequestMapping("/doLogin")
public String login(String name, String pwd, boolean remanaberMe, HttpSession session) {
/*获取主体*/
Subject subject = SecurityUtils.getSubject();
/*存储用户身份信息*/
AuthenticationToken token = new UsernamePasswordToken(name, pwd, remanaberMe);
try {
/*对用身份校验*/
subject.login(token);
System.out.println("登录成功");
session.setAttribute("user", token.getPrincipal().toString());
return "main";
} catch (UnknownAccountException e) {
System.out.println("账号不存在");
} catch (IncorrectCredentialsException e) {
System.out.println("密码错误");
} catch (AuthenticationException e) {
e.printStackTrace();
}
return "login";
}
配置类编写记住我
@Configuration
public class Config2 {
@Autowired
private MyRealm2 myRealm2;
/*配置SecurityManager*/
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*设置加密*/
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");/*加密类型*/
matcher.setHashIterations(2);/*迭代次数*/
myRealm2.setCredentialsMatcher(matcher);
securityManager.setRealm(myRealm2); /*设置自定义realm*/
securityManager.setRememberMeManager(rememberMeManager());/*设置记住我*/
return securityManager;
}
/*配置过滤器*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/login", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/**", "authc"); /*配置登录成功后放行路径*/
definition.addPathDefinition("/**", "user");
return definition;
}
/**
* 设置cookie
*/
public SimpleCookie rememberCookieManager() {
SimpleCookie cookie = new SimpleCookie();
cookie.setName("test");/*设置cookie名称*/
cookie.setPath("/"); /*cookie有效路径*/
cookie.setHttpOnly(true);
cookie.setMaxAge(30 * 24 * 60 * 60);/*cookie有效时间*/
return cookie;
}
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager
= new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberCookieManager());
cookieRememberMeManager.setCipherKey("1234567890123".getBytes());/*cookie加密*/
return cookieRememberMeManager;
}
}
退出登录实现
- 控制层编写退出控制单元
- 配置过滤器退出登录路径
编写退出控制单元
@RequestMapping("/loginOut")
public String loginOut() {
return "login";
}
配置类配置退出路径
@Configuration
public class Config2 {
@Autowired
private MyRealm2 myRealm2;
/*配置SecurityManager*/
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*设置加密*/
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");/*加密类型*/
matcher.setHashIterations(2);/*迭代次数*/
myRealm2.setCredentialsMatcher(matcher);
securityManager.setRealm(myRealm2); /*设置自定义realm*/
securityManager.setRememberMeManager(rememberMeManager());/*设置记住我*/
return securityManager;
}
/*配置过滤器*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/login", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/loginOut", "logout"); /*配置退出登录路径*/
definition.addPathDefinition("/**", "authc"); /*配置登录成功后放行路径*/
definition.addPathDefinition("/**", "user");
return definition;
}
/**
* 设置cookie
*/
public SimpleCookie rememberCookieManager() {
SimpleCookie cookie = new SimpleCookie();
cookie.setName("test");/*设置cookie名称*/
cookie.setPath("/"); /*cookie有效路径*/
cookie.setHttpOnly(true);
cookie.setMaxAge(30 * 24 * 60 * 60);/*cookie有效时间*/
return cookie;
}
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager
= new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberCookieManager());
cookieRememberMeManager.setCipherKey("1234567890123".getBytes());/*cookie加密*/
return cookieRememberMeManager;
}
}
授权
-
查询用户角色 、查询用户的权限
-
编写自定义的Realm类
-
编写角色控制和权限控制的单元
-
Shiro整合Thymeleaf页面控制授权, 用户是否显示按钮
编写自定义Realm,处理授权
@Component
public class MyRealm2 extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 自定义权限认证
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
/*获取身份*/
String principal = principalCollection.getPrimaryPrincipal().toString();
/*获取用户角色*/
List<String> roles = userService.findRole(principal);
/*获取用户权限*/
List<String> permissions = userService.findPermission(principal);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles); /*给用户添加角色信息*/
info.addStringPermissions(permissions); /*给用户添加权限信息*/
return info;
}
/**
* 自定义身份认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
/*获取身份*/
String principal = token.getPrincipal().toString();
/*身份验证*/
User login = userService.login(principal);
if (login!=null){
/*参数1:用户名,参数2:用户密码,参数3:盐值,参数4:真是名,没有什么用*/
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(principal, login.getPwd(),
ByteSource.Util.bytes(login.getSalt()), "test");
return info;
}
return null;
}
}
使用授权注解编写角色控制单元
/**
* 角色认证测试
*/
@RequiresRoles("role1")
@ResponseBody
@RequestMapping("/demo1")
public String demo1() {
return "角色认证测试";
}
使用授权注解编写权限控制单元
/**
* 权限认证测试
*/
@RequiresPermissions("sys:update")
@ResponseBody
@RequestMapping("/demo2")
public String demo2() {
return "demo2";
}
配置shiro 跟 thymeleaf 页面权限验证
/*配置shiro 跟 thymeleaf 页面权限验证*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
Thymeleaf页面权限控制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>主页面</title>
</head>
<body>
欢迎<span th:text="${session.user}"></span>
<br>
<a href="/loginOut">退出</a> <br>
<a shiro:hasRole="role1" href="/demo1">角色认证</a>
<a shiro:hasPermission="sys:update" href="/demo2">权限认证</a>
</body>
</html>
缓存管理
这里用Ehcache 做Shiro 的缓存
- 编写Ehcache配置文件
- 配置类配置Shiro缓存
Ehcache配置文件
maxElementsInMemory:缓存中允许创建的最大对象数。
eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
timeToIdleSeconds:缓存数据的钝化时间,取值0表示无限长。
timeToLiveSeconds:缓存数据的生存时间,取值0表示无限长。
overflowToDisk:内存不足时,是否启用磁盘缓存。
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。
<?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>
<!-- 记录用户的授权信息的缓存:缓存用户的角色和权限 -->
<cache name="authorizationInfo"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
</ehcache>
Shiro配置类 设置缓存
shiro 会自动管理 EhCacheManager 对用户信息进行缓存
@Configuration
public class Config2 {
@Autowired
private MyRealm2 myRealm2;
/*配置SecurityManager*/
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*设置加密*/
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");/*加密类型*/
matcher.setHashIterations(2);/*迭代次数*/
myRealm2.setCredentialsMatcher(matcher);
securityManager.setRealm(myRealm2); /*设置自定义realm*/
securityManager.setRememberMeManager(rememberMeManager());/*设置记住我*/
securityManager.setCacheManager(ehCacheManager());/*设置缓存管理*/
return securityManager;
}
/*配置过滤器*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/login", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/loginOut", "logout"); /*配置退出登录路径*/
definition.addPathDefinition("/**", "authc"); /*配置登录成功后放行路径*/
definition.addPathDefinition("/**", "user");
return definition;
}
/**
* 设置cookie
*/
public SimpleCookie rememberCookieManager() {
SimpleCookie cookie = new SimpleCookie();
cookie.setName("test");/*设置cookie名称*/
cookie.setPath("/"); /*cookie有效路径*/
cookie.setHttpOnly(true);
cookie.setMaxAge(30 * 24 * 60 * 60);/*cookie有效时间*/
return cookie;
}
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberCookieManager());
cookieRememberMeManager.setCipherKey("1234567890123".getBytes());/*cookie加密*/
return cookieRememberMeManager;
}
/*配置shiro 跟 thymeleaf 页面权限验证*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
/*配置缓存*/
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;
}
}
账号锁定
实现思路
- 将用户密码输出次数标记
- 存入缓存中
- 判断登录次数,进行锁定
- 缓存一定时间失效,用户可以再次登录
自定义凭证匹配
@Component
public class MyMatcher extends HashedCredentialsMatcher {
private Ehcache passwordRetryEhcache;
//声明构造方法获取缓存对象
public MyMatcher(EhCacheManager ehCacheManager) {
passwordRetryEhcache = ehCacheManager.getCacheManager().getCache("authorizationInfo");
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
//声明变量记录错误次数
int i = 0;
/*获取用户的登录次数的缓存信息*/
//获取用户的身份信息(身份信息为缓存数据的键名)
String username = token.getPrincipal().toString();
System.out.println("账号锁定方法" + username);
//获取缓存对象
Element element = passwordRetryEhcache.get(username);
/*判断是否有缓存数据*/
if (element == null) {//没有缓存登录的错误次数,则创建新的缓存
Element ele = new Element(username, new AtomicInteger(0));
passwordRetryEhcache.put(ele);
} else {
/*有缓存直接递增*/
AtomicInteger atomicInteger = (AtomicInteger) element.getObjectValue();
i = atomicInteger.incrementAndGet();
}
System.out.println("登录认证失败次数:" + i);
/*判断登录次数*/
if (i >= 2) {
System.out.println("登录次数过多");
throw new ExcessiveAttemptsException();
}
/* 进行本次请求的登录*/
boolean flag = super.doCredentialsMatch(token, info);
if (flag) {
passwordRetryEhcache.remove(username);
}
return flag;
}
}
配置凭证匹配
@Configuration
public class Config2 {
@Autowired
private MyRealm2 myRealm2;
@Autowired
private MyMatcher myMatcher;
/*配置SecurityManager*/
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*设置加密*/
myMatcher.setHashAlgorithmName("md5");/*加密类型*/
myMatcher.setHashIterations(2);/*迭代次数*/
myRealm2.setCredentialsMatcher(myMatcher);
securityManager.setRealm(myRealm2); /*设置自定义realm*/
securityManager.setRememberMeManager(rememberMeManager());/*设置记住我*/
securityManager.setCacheManager(ehCacheManager());/*设置缓存管理*/
return securityManager;
}
/*配置过滤器*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/login", "anon"); /*配置登录放行路径*/
definition.addPathDefinition("/loginOut", "logout"); /*配置退出登录路径*/
definition.addPathDefinition("/**", "authc"); /*配置登录成功后放行路径*/
definition.addPathDefinition("/**", "user");
return definition;
}
/**
* 设置cookie
*/
public SimpleCookie rememberCookieManager() {
SimpleCookie cookie = new SimpleCookie();
cookie.setName("test");/*设置cookie名称*/
cookie.setPath("/"); /*cookie有效路径*/
cookie.setHttpOnly(true);
cookie.setMaxAge(30 * 24 * 60 * 60);/*cookie有效时间*/
return cookie;
}
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberCookieManager());
cookieRememberMeManager.setCipherKey("1234567890123".getBytes());/*cookie加密*/
return cookieRememberMeManager;
}
/*配置shiro 跟 thymeleaf 页面权限验证*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
/*配置缓存*/
@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;
}
}
SessionManager
通过Subject 获取Session ,跟HttpSession 用法一样
获取Session
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();