目录

1.shiro集成 spring

1.1 导入依赖的包

1.2 web.xml配置

2. 开发自定义Realm

2.1 创建测试数据表

2.3 编写后台支持服务

2.4 编写自定义的Realm

2.5配置文件 放入spring 中

2.6登录Controller

3.权限管理 登录后

1. 自定义Realm 此处上面的Realm中已有代码

2.权限标签

3. 使用注解控制权限

3.1 springMVC配置

4.2 注解权限验证失败不跳转路径问题

4. shiro中的缓存

1.1 引入需要的第三方包

1.2 ehcache配置文件

1.2 配置spring的配置文件

2. shiro中的session

2.1 shiro中的session特点和常用方法

2.2 如何使用

2.3 Session监听

2.4 SessionDao 将数据报错数据库 让后同步数据


1.shiro集成 spring

1.1 导入依赖的包

导入shiro需要的依赖包

<shiro-version>1.2.5</shiro-version>
​
<dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-core</artifactId>    <version>${shiro-version}</version>
</dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-web</artifactId>    <version>${shiro-version}</version></dependency>
<dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-spring</artifactId>    <version>${shiro-version}</version>
</dependency>

1.2 web.xml配置

<!-- shiro -->
<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>

2. 开发自定义Realm

2.1 创建测试数据表

获取地址:shiro测试数据 密码:3kvh

创建好 实体 model

2.3 编写后台支持服务

用户 mapper 接口 编写

package com.zking.shiro.mapper;
​
import com.zking.shiro.model.User;
import org.springframework.stereotype.Repository;
​
import java.util.Set;
​
@Repository
public interface IUserMapper {/*** 用户登录功能* @param us* @return*/User login(User us);
​/***  获取用户信息* @param userName* @return*/Set<String> getRolesByUserName(String userName);
​/*** 通过用户名称获取权限信息* @param userName* @return*/Set<String> getPermissionsByUserName(String userName);
}
​

用户 mybatis xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zking.shiro.mapper.IUserMapper">
<!--  用户登录功能 --><select id="login" resultType="com.zking.shiro.model.User">select user_id userId,username userName,password ,salt,locked,create_datetime createDatetime from t_sys_user<where>username = #{userName}</where></select>
​<select id="getRolesByUserName" resultType="java.lang.String">SELECT t2.role_nameFROM `t_sys_user` t join t_sys_user_role t1 on t.user_id =t1.user_id join t_sys_role t2 on t1.role_id = t2.role_id<where>t.username= #{userName}</where></select>
​
​<select id="getPermissionsByUserName" resultType="java.lang.String">SELECT t4.permissionFROM `t_sys_user` t join t_sys_user_role t1 on t.user_id =t1.user_id join t_sys_role t2 on t1.role_id = t2.role_id joint_sys_role_permission t3 on t2.role_id = t3.role_id join t_sys_permissiont4 on t3.permission_id=t4.permission_id<where>t.username= #{userName}</where></select>
​
​
</mapper>

编写 service 省略

2.4 编写自定义的Realm

shiro中的Realm UML:

package com.zking.shiro.shiro;
​
import com.zking.shiro.model.User;
import com.zking.shiro.service.IUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
​
import java.util.Objects;
​
​
public class CustomerRealm extends AuthorizingRealm {@Autowiredprivate IUserService userService;
​/*** 提供授权信息* @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String username =principalCollection.getPrimaryPrincipal().toString();SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//放入用户信息 用户身份info.setRoles(userService.getRolesByUserName(username));//获取用户所拥有的权限info.setStringPermissions(userService.getPermissionsByUserName(username));return info;}
​/*** 提供认证信息* @param authenticationToken* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {String username =authenticationToken.getPrincipal().toString();User user = new User();user.setUserName(username);User db_login = userService.login(user);if(Objects.isNull(db_login)){throw new UnknownAccountException("用户 :" +username +"不存在");}//这里 可以写死 为 1  此处在用户实体中定义了一个常量if(db_login.getLocked() == User.USER_LOCKED){throw new LockedAccountException("用户 :" +username +"被锁定");}//此处考虑了加密 所以我们需要准备 md5 的加密//告诉 shiro 我的md5 加密盐为 ByteSource.Util.bytes(db_login.getSalt())SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(db_login.getUserName(), db_login.getPassword(), ByteSource.Util.bytes(db_login.getSalt()),this.getName());return simpleAuthenticationInfo;}
}

2.5配置文件 放入spring 中

​<!-- 自定义的Realm --><bean id="customerRealm" class="com.zking.shiro.shiro.CustomerRealm"><property name="credentialsMatcher"><bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><!--指定hash算法为MD5--><property name="hashAlgorithmName" value="md5"/><!--指定散列次数为1024次--><property name="hashIterations" value="1024"/><!--true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储--><property name="storedCredentialsHexEncoded" value="true"/></bean></property></bean>
​<!--  注册 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="customerRealm"/>
</bean>
​
​<!--Shiro核心过滤器--><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- Shiro的核心安全接口,这个属性是必须的 --><property name="securityManager" ref="securityManager" /><!-- 身份验证失败,跳转到登录页面 --><property name="loginUrl" value="/"/><!-- 身份验证成功,跳转到指定页面 --><!--<property name="successUrl" value="/index.jsp"/>--><!-- 权限验证失败,跳转到指定页面 --><!--<property name="unauthorizedUrl" value="/user/noauthorizeUrl"/>--><!-- Shiro连接约束配置,即过滤链的定义 --><property name="filterChainDefinitions"><value><!--注:anon,authcBasic,auchc,user是认证过滤器perms,roles,ssl,rest,port是授权过滤器--><!--anon 表示匿名访问,不需要认证以及授权--><!--authc表示需要认证 没有进行身份认证是不能进行访问的--><!--roles[admin]表示角色认证,必须是拥有admin角色的用户才行-->/user/login=anon/book/**=authc/common/**=authc<!-- /css/**           = anon/images/**            = anon/js/**                = anon/                     = anon/user/logout          = logout/user/**              = anon/userInfo/**          = authc/dict/**              = authc/console/**           = roles[admin]/**                   = anon--></value></property></bean>
​<!-- Shiro生命周期,管理shiro bean的生命周期 --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
​

md5加密

注: MD5 MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5算法是不可逆的,即便得到了加密以后的密文,也不可能通过解密算法反算出明文。 用途: 1)密码管理,如用户密码的MD5加密后再保存数据库 2)电子签名,MD5 算法还可以作为一种电子签名的方法来使用,使用 MD5算法就可以为任何文件(不管其大小、格式、数量)产生一个独一无二的“数字指纹”,借助这个“数字指纹”,通过检查文件前后 MD5 值是否发生了改变,就可以知道源文件是否被改动。(回想一下JWT的令牌签名)

2.6登录Controller

package com.zking.shiro.controller;
​
import com.sun.prism.impl.shape.ShapeUtil;
import com.zking.shiro.model.User;
import com.zking.shiro.service.IUserService;
import com.zking.shiro.utils.RetrunData;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
​
import javax.servlet.http.HttpSession;
import java.util.HashMap;
​
@Controller
/* 访问时 需要添加 user */
//@RequestMapping("/user")
public class UserController {@RequestMapping("/")public String index(){return "login";}@RequestMapping("/user/login")public String login(User us, Model model, HttpSession session){Subject subject= SecurityUtils.getSubject();UsernamePasswordToken passwordToken =new            UsernamePasswordToken(us.getUserName(), us.getPassword());try{subject.login(passwordToken);}catch (UnknownAccountException | LockedAccountException e){model.addAttribute("message",e.getMessage());return "login";}catch (AuthenticationException e){model.addAttribute("message","账号或密码错误");return "login";}session.setAttribute("user",us);return "index";}
​
}
​

登录界面 注意此处 可能 会有所不同

 <%--Created by IntelliJ IDEA.User: lisensirDate: 2022/6/22Time: 22:20To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page pageEncoding="utf-8" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>登录页面</h1>
${message}
<form id="loginForm" action="<%=request.getContextPath()%>/user/login" method="post"><input type="text" id="userName" name="userName"/> <br/><input type="text" id="password" name="password"/>  <br/><input type="submit" value="登录"/>
</form>
</body>
</html>
​

3.权限管理 登录后

1. 自定义Realm 此处上面的Realm中已有代码

2.权限标签

2.1 引入标签库

<%@taglib prefix="shiro" uri="Taglib | Apache Shiro" %>

Shiro标签库 guest标签 :验证当前用户是否为“访客”,即未认证(包含未记住)的用户 user标签 :认证通过或已记住的用户 authenticated标签 :已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在 notAuthenticated标签 :未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户 principal 标签 :输出当前用户信息,通常为登录帐号信息 hasRole标签 :验证当前用户是否属于该角色 lacksRole标签 :与hasRole标签逻辑相反,当用户不属于该角色时验证通过 hasAnyRole标签 :验证当前用户是否属于以下任意一个角色 hasPermission标签 :验证当前用户是否拥有指定权限 lacksPermission标签 :与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过

2.2 使用标签控制权限

注:只是用于演示权限标签,如果有权限则显示功能连接,否则不显示,所以并没有指定具体的链接。

<%--Created by IntelliJ IDEA.User: lisensirDate: 2022/6/23Time: 11:09To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="http://shiro.apache.org/tags" %>
<html>
<head><title>Title</title>
</head>
<body>
<s:hasRole name="admin">
<h1>管理员</h1>
</s:hasRole>
​
​
<s:hasPermission name="system:dict:view">
<li><a href="#">书本查询</a></li>
</s:hasPermission>
<s:hasPermission name="system:dict:add"><li><a href="#">书本新增</a></li>
</s:hasPermission>
<s:hasPermission name="bookmanager:book:edit"><li><a href="#">书本修改</a></li>
</s:hasPermission>
<s:hasPermission name="bookmanager:book:del"><li><a href="#">书本删除</a></li>
</s:hasPermission>
​
<a href="<%=request.getContextPath()%>/userRealm">测试</a>
​
</body>
</html>
​

权限需要根据数据库 查看

3. 使用注解控制权限

常用注解: @RequiresAuthenthentication:表示当前Subject已经通过login进行身份验证;即 Subject.isAuthenticated()返回 true @RequiresUser:表示当前Subject已经身份验证或者通过记住我登录的 @RequiresGuest:表示当前Subject没有身份验证或者通过记住我登录过,即是游客身份 @RequiresRoles(value = {"admin","user"},logical=Logical.AND):表示当前Subject需要角色admin和user @RequiresPermissions(value = {"user:delete","user:b"},logical = Logical.OR):表示当前Subject需要权限user:delete或者user:b

3.1 springMVC配置

开启注解,必须将Shiro注解的开启放置到spring-mvc.xml中(即放在springMVC容器中加载),否则Shiro注解开启无效


  <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"><property name="proxyTargetClass" value="true"></property>
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"/>
</bean>

在Controller中加入用于演示的请求处理器:

在index.jsp中加入功能连接,用于演示权限控制。

4.2 注解权限验证失败不跳转路径问题

问题原因:由于我们架构是用springmvc框架来搭建的所以项目的路径跳转是由springmvc 来控制的,也就是说我们在shiro里面的配置没有用

解决 springmvc中有一个org.springframework.web.servlet.handler.SimpleMappingExceptionResolver类就可以解决这个问题

<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="org.apache.shiro.authz.UnauthorizedException">unauthorized</prop></props></property></bean>

编写一个用于提示没有权限的页面,页面名称为unauthorized,与上面的配置文件中配置的保持一致,、

<%--Created by IntelliJ IDEA.User: lkfDate: 2022/9/6Time: 19:13To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1> 权限不足 </h1>
</body>
</html>

4. shiro中的缓存

在权限验证时每次从数据库中获取权限数据显然是不合适的,更合适方式是将数据缓存到内存,以提高系统性能,shiro中可以方便的配置缓存,具体的配置如下:

1.1 引入需要的第三方包

 <!-- shiro依赖包 -->
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro-version}</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro-version}</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro-version}</version>
</dependency>
​<!-- 缓存需要的包 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>${shiro-version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring-version}</version></dependency>

1.2 ehcache配置文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"updateCheck="false">
​<diskStore path="java.io.tmpdir"/><defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
​
​<!--name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)--><!--  <cache name="stuCache" eternal="false" maxElementsInMemory="100"overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU"/> -->
</ehcache>

1.2 配置spring的配置文件

<!-- shiro 缓存-->
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"><property name="configLocation" value="classpath:ehcache.xml"/><property name="shared" value="true"></property>
</bean>
<bean id="shrioEhcache" class="org.apache.shiro.cache.ehcache.EhCacheManager"><property name="cacheManager" ref="cacheManagerFactory"></property>
</bean>
//此安全管理器 上方配置文件中 已经带有 只需要 把下面的缓存配置  加进去即可
<!-- 将自定义的realm注入到安全管理器中 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="shiroRealm" /><!-- 为安全管理器配置缓存 --><property name="cacheManager" ref="shrioEhcache"></property>
</bean>

2. shiro中的session

2.1 shiro中的session特点和常用方法

shiro的session和httpsession概念上是相同的,指定都是客户端和服务器之间的一次会话。 shiro的session的特点如下:

  • 不依赖于底层的容器(比如Tomcat),httpsession是依赖于底层容器的,这意味中shiro的session可以脱离容器使用

  • 提供了会话管理,会话监听,会话存储等功能, 可以支持会话过期,实现单点登录等。

常用的方法: Subject.getSession(true/false) 获取session,如果为参数为true,则没有session时会创建session,如果为false则没有session返回空 session.getId() 获取当前会话的ID号 session.getHost() 获取当权会话的主机地址 session.getTimeout() 获取过期时间 session.setTimeout() 设置当前时间 session.getStartTimestamp() 获取会话启动的时间戳 session.getLastAccessTime() 获取会话的最后访问时间 session.touch() 更新最后一次访问时间 session.stop() 销毁会话 session.setAttribute(kay,val) session.getAttribute(key) session.removeAttribute(key)

shiro中的session也提供了监听器,和HttpSessionListener类似,提供如下方法: onStart() -- 监听启动事件 onStop() -- 监听停止事件 onExpiration() -- 监听过期事件

2.2 如何使用

shiro中的session使用起来非常简单,通过设置在中的数据,可以在Shiro的Session中直接获取 通过 shiro中的session保存的数据 通过 HttpSession 也一样可以获取

  @PostMapping("/user")public String getUser(User user, Model model, HttpSession session) {
​session.setAttribute("uname", user.getUsername());//两者都同步数据System.out.println(session.getAttribute("us"));...}
@Service
public class SessionService implements ISessionService {
​@Overridepublic void testSession() {//在service中通过Subject获取session使用,这里的uname属性是通过HttpSession类设置的Session session = SecurityUtils.getSubject().getSession();System.out.println("===== session : " + session.getAttribute("uname"));SecurityUtils.getSubject().getSession().setAttribute("us","haoya");}
}

如何验证缓存配置的有效性:

  • 首先不配置缓存,在自定义的Realm中输出一些提示信息,启动服务后会发现每次调用登录,或其他配置了权限认证的功能,都会输出提示信息

  • 配置缓存,然后重新运行相同的通过,查看后台,加载一次后及不会再有输出

2.3 Session监听

用于监听session的创建,过期等事件,如果在需要时可以再session创建时做些初始化操作,或在过期时做些清理操作。

1) 创建一个自定义监听器

@Slf4j
public class SessionListener extends SessionListenerAdapter {
​@Overridepublic void onStart(Session session) {log.info("Shiro session onStart .... ");}
​@Overridepublic void onStop(Session session) {log.info("Shiro session onStop .... ");}
​@Overridepublic void onExpiration(Session session) {log.info("Shiro session onExpiration ....");}
​
}

2)配置文件,在spring配置文件中做如下配置

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="shiroRealm" /><!-- 注入缓存管理器 --><property name="cacheManager" ref="shrioEhcache"/>//只需要在 shiro的安全管理器中配置 下一条即可  <!-- session管理器 --><property name="sessionManager" ref="sessionManager"/></bean>
​<!-- session管理器 ,配置自定义监听器,同时需要将该sessionManager配置到securityManager中--><bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><property name="sessionListeners"><list>//此路径 需要配置你在及项目中过滤器<bean class="com.zking.shirodemo.listener.SessionListener"/></list></property></bean>

2.4 SessionDao 将数据报错数据库 让后同步数据

首先先编写 数据访问层 mapper 接口定义

package com.zking.shiro.mapper;
​
import com.zking.shiro.model.SessionModel;
import org.springframework.stereotype.Repository;
​
@Repository
public interface ISessionMapper {
​void addSession(SessionModel session);
​SessionModel getSession(SessionModel session);
​void delSession(SessionModel session);
​void updateSession(SessionModel session);
​
​
}

xml 实现

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zking.shiro.mapper.ISessionMapper">
​
​<insert id="addSession">insert into t_sys_session(session_id,session) values (#{sessionid},#{session})</insert><update id="updateSession">update  t_sys_session <set><if test="session != null">session = #{session}</if></set><where>and session_id=#{sessionid}</where></update>
​<delete id="delSession">delete from t_sys_session where session_id=#{sessionid}</delete><select id="getSession" resultType="com.zking.shiro.model.SessionModel">select id,session_id sessionid,session from t_sys_session where session_id= #{sessionid}</select>
</mapper>

自行编写 service 层 !!!!

实现自定义SessionDao的步骤:

  • 编写自定义的SessionDao,集成自EnterpriseCacheSessionDao

  • 增删改查

  • 保存方式选择了json 下方有工具包 代码

package com.zking.shiro.listener;
​
import com.zking.shiro.model.SessionModel;
import com.zking.shiro.service.ISessionService;
import com.zking.shiro.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.beans.factory.annotation.Autowired;
​
import java.io.Serializable;
import java.util.Objects;
​
/*** 自定义Session持久化,将Shiro的Session数据保存到数据库中。* 完成该类的编写后,需要在spring配置文件中进行配置*/
@Slf4j
public class DbSessionDao extends EnterpriseCacheSessionDAO {@Autowiredprivate ISessionService service;
​@Overrideprotected Serializable doCreate(Session session) {Serializable sid = super.doCreate(session);SessionModel sessionModel = new SessionModel();sessionModel.setSessionid(sid.toString());//把session转为json保存sessionModel.setSession(JsonUtils.toJson(session));log.debug("将session保存到数据库, sessionId = {}", sid);service.addSession(sessionModel);return sid;}
​@Overrideprotected Session doReadSession(Serializable sessionId) {
​Session session = super.doReadSession(sessionId);
​//如果从内存中获取了session,则直接返回if (!Objects.isNull(session)) {log.debug("从内存中获取session,sessionId = " + sessionId + ", 直接返回");return session;}
​log.debug("从内存中没有获取到session,id={}, 将从数据库获取session", sessionId);SessionModel model = new SessionModel();model.setSessionid(sessionId.toString());SessionModel session1 = service.getSession(model);
​if(Objects.isNull(session1)) {log.debug("数据库中也没有找到id={}的session,将返回null");return session;}session  = (Session) JsonUtils.toJson(session1.getSession(),Session.class);
​return session;}
​@Overrideprotected void doDelete(Session session) {SessionModel model=new SessionModel();model.setSessionid(session.getId().toString());log.debug("删除session,sessionId: " + session.getId().toString());service.delSession(model);super.doDelete(session);}
​
​@Overrideprotected void doUpdate(Session session) {
​String sessionId = session.getId().toString();SessionModel tmpModel = new SessionModel();tmpModel.setSessionid(sessionId);SessionModel model = service.getSession(tmpModel);
​if(Objects.isNull(model)) {//检查 session 是否 有效 无效 就不加入数据库Object obj = session.getAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY);
​//数据库中是否有session,如果没有检查session无效,则直接返回,否则保存到数据库中if(Objects.isNull(obj) || !Boolean.parseBoolean(obj.toString())) {return ;}
​SessionModel saveModel = new SessionModel();saveModel.setSessionid(session.getId().toString());saveModel.setSession(JsonUtils.toJson(session));log.debug("session已经过验证,且在数据库中不存在,将session保存到数据库 ..... ");service.addSession(saveModel);} else {//如果session在数据库中已存在,则更新sessionmodel.setSession(JsonUtils.toJson(session));log.debug("session在数据库中已存在,将session更新到数据库 ..... ");service.updateSession(model);}
​//调用父类方法,更新sessionsuper.doUpdate(session);}
}
​

使用的json工具

依赖文件

 <!-- 导入解析 Json的包  --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.3</version></dependency>

工具包

package com.zking.shiro.utils;
​
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
​
public final class  JsonUtils {private JsonUtils(){}private static ObjectMapper map = new ObjectMapper();
​/*** 将 对象转字符串** @param obj* @return*/public static String toJson(Object obj) {
​String s = null;try {s = map.writeValueAsString(obj);} catch (JsonProcessingException e) {throw new RuntimeException(e);}
​return s;}
​/*** 将 json字符串 转为 对象** @param json* @return*/public static  <T> Object toJson(String json, T t) {
​
​try {return map.readValue(json, t.getClass());} catch (JsonProcessingException e) {throw new RuntimeException(e);}}
​
}

在 spring 配置文件中配置 时效

 <!-- session管理器 ,配置自定义监听器,同时需要将该sessionManager配置到securityManager中-->
  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><property name="sessionListeners"><list><bean class="com.zking.shiro.listener.SessionListener"/></list></property>
​<!-- 配置 session 关闭服务器有效 session持久化  --><!-- 删除失效session --><property name="sessionValidationSchedulerEnabled" value="true" /><!-- session失效时间(毫秒) --><property name="globalSessionTimeout" value="1800000" /><property name="sessionDAO" ref="customShiroSessionDao" /></bean>

将session 管理器配置到shiro 管理器中 刚刚以及配置过

shiro集成 spring-加密md5配置--权限管理-shiro中的session 等等!!相关推荐

  1. 基于shiro+jwt的真正rest url权限管理,前后端分离

    代码地址如下: http://www.demodashi.com/demo/13277.html bootshiro & usthe bootshiro是基于springboot+shiro+ ...

  2. java.securti_springboot集成springsecurity 使用OAUTH2做权限管理的教程

    Spring Security OAuth2 主要配置,注意application.yml最后的配置resource filter顺序配置,不然会能获取token但是访问一直 没有权限 WebSecu ...

  3. Spring Security + JWT实现权限管理

    1 写在之前 本博客主要使用Spring Boot 整合Spring Security + JWT实现权限管理,利用JWT工具生成token,返回给登录接口.在访问其他接口时,采用Bearer Tok ...

  4. Shiro笔记(二)Shiro集成SpringMVC的环境配置

    0.pom文件引入 <!-- SECURITY begin --><dependency><groupId>org.apache.shiro</groupId ...

  5. 用Spring Security做分布式权限管理 - 卷一基本功

    我们但凡做一个系统,这个系统不是在封闭环境中,不是只给一个人用,为了保证系统与数据安全,那么就会涉及到权限控制,权限控制这个东西可以说是很多系统的基础,因为我们不能让所有人对系统上的所有资源都进行同样 ...

  6. 【Java从0到架构师】项目实战 - 会话管理、EhCache、JWT、权限管理 Shiro、打包部署

    项目实战 - 权限管理 会话管理 客户端身份认证 - 基于 Cookie.Session 客户端身份验证 - 基于 token EhCache - 简单的缓存框架 JWT - 基于 JSON 的 to ...

  7. 用户权限管理shiro

    2019独角兽企业重金招聘Python工程师标准>>> 关于权限管理的一些配置只是为了让自己方便查询和总结. 1. 首先在pom.xml中引入需要的包. <project xm ...

  8. 权限管理(shiro框架)

    为什么80%的码农都做不了架构师?>>>    1. 权限管理的流程 页面中的菜单和按钮就是我们访问某个功能的入口. 无论是访问菜单或者按钮,要想完成某个业务操作,实际上是需要发送一 ...

  9. Shiro集成Spring框架并且多Realms报错No realms have been configured! One or more realms must be ……解决办法

    博主今天在做Shiro集成SpringMVC实现多Reamls的时候,报了No realms have been configured! One or more realms must be --的错 ...

最新文章

  1. mysql 资深dba_MySQL数据库专家分享资深DBA经验
  2. python代码怎么运行-python代码如何运行
  3. 成都Uber优步司机奖励政策(4月8日)
  4. 后台excel导出(单sheet 多sheet)
  5. 实现mvcc_一文读懂 etcd 的 mvcc 实现
  6. QT每日一练day25:触发绘画事件
  7. java三大框架增删改查_Java_Web三大框架之Hibernate增删改查
  8. Python:日志模块logging的应用
  9. QWidget QMainWindow QDialog 三者区别
  10. 如何通过自定义属性设置PDMS模型颜色
  11. 傅里叶变换1 ~ 离散时间傅里叶变换(DTFT)
  12. MSSQL 2000安装 图解
  13. 【R】R语言windows下连接MySQL
  14. 南银法巴消费金融完成增资,苏宁清仓出局
  15. 求部门最高工资(Mysql多表查询)
  16. Spring Cloud微服务系统架构的一些简单介绍和使用
  17. 微型计算机在cad和cam中,CAM CAD考试题
  18. 2023年美国大学生数学建模竞赛赛题发布【英文原文 中文翻译】
  19. 【三层交换机的配置】
  20. java美容美发项目下载_汉之源美容美发管理系统

热门文章

  1. 下班后如何进行自我提升?掌握这六种技能,你的人生会从此开挂
  2. 输入法中英文状态悬浮提示,利用AutoHotkey实现【转载】+我的使用感受
  3. jQuery中queue和dequeue的用法
  4. metadata-complete讲解
  5. Lecture 12 : Nonlinear Transformation
  6. Arduino学习(八) 数码管
  7. realme双12真我GT大师探索版2499元起,还可1212元买入
  8. BUUCTF axb_2019_fmt32(格式化字符串漏洞)
  9. 在C++中使用SCIP求解器
  10. 计算机网络——TCP 协议总结