SpringBoot+Shiro+mybatis整合

1. 使用Springboot版本2.0.4 与shiro的版本

引入springboot和shiro依赖

<?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.smile</groupId>
<artifactId>spring-demo</artifactId>
<version>1.0-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency> <!-- mysql所需的配置 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency> <dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency> <!--阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency> <!-- Redis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency> <!-- 读取资源文件所需的配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency> <!-- 引入thymeleaf模板依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> <!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency> <!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency> <!-- 集成shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.crazycake/shiro-redis -->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>3.1.0</version>
</dependency> <!-- 打印SQL语句-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> </dependencies>
</project>

2. 添加相应的配置

server:
port: 8183 spring:
thymeleaf:
mode: HTML
encoding: utf-8
cache: false
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.144.128:3306/spring_shiro?serverTimezone=GMT&useUnicode=true&characterEncoding=utf-8&useSSL=true
#url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
maxActive: 20
initialSize: 1
maxWait: 60000
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 1 from dual
testWhileIdle: true
testOnBorrow: false
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss jpa:
database: mysql
show-sql: true #日志级别打印
logging:
level:
com.example.demo: debug
org.springframework: WARN
org.spring.springboot.dao: debug # MyBatis
mybatis:
typeAliasesPackage: com.example.demo
mapperLocations: classpath:mybatis/**/*Mapper.xml
configLocation: classpath:mybatis/mybatis-config.xml # PageHelper
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql

3. 将相关配置@Bean注入容器

package com.example.demo.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.LinkedHashMap;
import java.util.Map; /**
* @时间 2019/11/25 17:17
* @作者 liutao
* @描述
*/
@Configuration
public class ShiroConfig { /**
* 设置过滤器
* @param securityManager
* @return
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
// 设置需要进行登录的路径API
factoryBean.setLoginUrl("/pub/need_login");
// 若是使用前后端分离,则不需要进行设置该方法
factoryBean.setSuccessUrl("/");
// 没有进行授权,返回的API
factoryBean.setUnauthorizedUrl("/pub/not_permit"); // 自定义过滤器 Map<String, String> filterMap = new LinkedHashMap<>();
// 设置退出的过滤器
filterMap.put("/logout", "logout");
// 不需要进行授权就可以进行访问,游客都可以进行访问的API
filterMap.put("/pub/**", "anon");
// 需要进行授权才可以进行访问的API接口
filterMap.put("/authc/**", "authc");
// 有对应的角色才可以进行访问
filterMap.put("/admin/**", "roles[admin]"); // 设置最后的拦截器,需要进行授权才可以进行访问
filterMap.put("/**","authc");
factoryBean.setFilterChainDefinitionMap(filterMap); return factoryBean;
} /**
* 设置安全管理器
* @return
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setSessionManager(sessionManager());
securityManager.setRealm(customRealm());
securityManager.setCacheManager(cacheManage());
return securityManager;
} /**
* 自定义Realm
* @return
*/
@Bean
public CustomRealm customRealm(){
CustomRealm customRealm = new CustomRealm();
// 设置密码的加密
customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return customRealm;
} /**
* 设置sessionId的管理器 (前后端分离,要进行获取Token)
* @return
*/
@Bean
public SessionManager sessionManager(){
CustomSessionManager sessionManager = new CustomSessionManager();
// 设置sessionDAO -- 里面定义了自定义SessionId
sessionManager.setSessionDAO(redisSessionDAO());
return sessionManager;
} /**
* 设置密码加密
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
// 密码算法
matcher.setHashAlgorithmName("md5");
// 加密散列次数
matcher.setHashIterations(3);
return matcher;
} /**
* 将会话SessionId保存到Redis里面,可以提高性能
* @return
*/
public RedisSessionDAO redisSessionDAO(){
RedisSessionDAO dao = new RedisSessionDAO();
dao.setRedisManager(redisManager());
dao.setSessionIdGenerator(new CustomSessionIdGenerator());
return dao;
} /**
* 接入Redis数据库
* @return
*/
public RedisManager redisManager(){
RedisManager redisManager = new RedisManager();
redisManager.setHost("127.0.0.1");
redisManager.setPort(6379);
return redisManager;
} /**
* 缓存管理
* @return
*/
@Bean
public RedisCacheManager cacheManage(){
RedisCacheManager cacheManager = new RedisCacheManager();
cacheManager.setRedisManager(redisManager());
// 设置过期时间,单位是秒
cacheManager.setExpire(60);
return cacheManager;
} /**
* 加入请求头 前后端分离
* @return
*/
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfig();
} }

4.创建CustomRealm类继承AuthorizingRealm,实现用户登录认证和权限鉴权

package com.example.demo.config;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired; /**
* @时间 2019/11/25 17:17
* @作者 liutao
* @描述
*/
public class CustomRealm extends AuthorizingRealm { @Autowired
private UserService userService; /**
* 鉴权
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String name = (String) principals.getPrimaryPrincipal();
    //若是使用Redis和cache,获取信息转成用户对象
    // User user= (User) principals.getPrimaryPrincipal();
    return null;
} /**
* 登录认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String name = (String) token.getPrincipal(); User user = userService.selectUserByName(name);
if(user == null){
return null;
}
     // 若是加入Redis和Cache缓存的管理的话,需要返回 用户对象
     //new SimpleAuthenticationInfo(user,user.getPassword(),getName());
    return new SimpleAuthenticationInfo(name,user.getPassword(),getName());
}
}

5. 创建CustomSessionManager继承DefaultWebSessionManager,可以进行实现Token,进行重写

package com.example.demo.config;

import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable; /**
* @时间 2019/11/25 17:18
* @作者 liutao
* @描述
*/
public class CustomSessionManager extends DefaultWebSessionManager { private static final String AUTHORIZATION = "token"; public CustomSessionManager(){
super();
} @Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) { String sessionId = WebUtils.toHttp(request).getHeader(AUTHORIZATION); if(sessionId != null){ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);
//automatically mark it valid here. If it is invalid, the
//onUnknownSession method below will be invoked and we'll remove the attribute at that time.
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return sessionId;
}else{
return super.getSessionId(request,response);
} } }

6. 实现自定义SessionId,创建CustomSessionIdGenerator类实现 SessionIdGenerator

package com.example.demo.config;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator; import java.io.Serializable;
import java.util.UUID; /**
* @时间 2019/11/26 16:30
* @作者 liutao
* @描述
*/
public class CustomSessionIdGenerator implements SessionIdGenerator { private final String PREFIX_SESSIONID = "cc0504"; public CustomSessionIdGenerator(){
super();
} @Override
public Serializable generateId(Session session) {
return PREFIX_SESSIONID + UUID.randomUUID().toString().replaceAll("-","");
}
}

7.前后端分离,在Header里面加入相应的数据信息

package com.example.demo.config;

import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /**
* @时间 2019/11/25 19:27
* @作者 liutao
* @描述
*/
public class WebMvcConfig implements WebMvcConfigurer { @Override
public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**")
.allowedOrigins("*") //可访问ip,ip最好从配置文件中获取,
.allowedMethods("PUT", "DELETE","GET","POST")
.allowedHeaders("*")
.exposedHeaders("access-control-allow-headers","access-control-allow-methods","access-control-allow-origin", "access-control-max-age","X-Frame-Options")
.allowCredentials(false).maxAge(3600); }
}

8. mybatis的配置

# MyBatis
mybatis:
typeAliasesPackage: com.example.demo
mapperLocations: classpath:mybatis/**/*Mapper.xml
configLocation: classpath:mybatis/mybatis-config.xml

mybatis-config.xml中的内容:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <settings>
<setting name="cacheEnabled" value="true" /> <!-- 全局映射器启用缓存 -->
<setting name="useGeneratedKeys" value="false" /> <!-- 不允许 JDBC 支持自动生成主键 -->
<setting name="defaultExecutorType" value="REUSE" /> <!-- 配置默认的执行器 -->
<!--<setting name="logImpl" value="SLF4J" />--> <!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="STDOUT_LOGGING" /> <!-- 在控制台打印SQL语句 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> 驼峰式命名 -->
</settings> </configuration>

基础Mapper.xml文件内容

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<resultMap id="userResultMap" type="User">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="password" property="password"/>
<result column="salt" property="salt"/>
</resultMap> <select id="selectAllUsers" resultMap="userResultMap">
select * from sys_user
</select> <select id="selectUserByName" resultMap="userResultMap">
select * from sys_user where name = #{name}
</select>
</mapper>

SpringBoot+Shiro+mybatis整合实战的更多相关文章

  1. 30分钟带你了解Springboot与Mybatis整合最佳实践

    前言:Springboot怎么使用想必也无需我多言,Mybitas作为实用性极强的ORM框架也深受广大开发人员喜爱,有关如何整合它们的文章在网络上随处可见.但是今天我会从实战的角度出发,谈谈我对二者结 ...

  2. SpringBoot与Mybatis整合方式01(源码分析)

    前言:入职新公司,SpringBoot和Mybatis都被封装了一次,光用而不知道原理实在受不了,于是开始恶补源码,由于刚开始比较浅,存属娱乐,大神勿喷. 就如网上的流传的SpringBoot与Myb ...

  3. springboot shiro 基本整合

    springboot shiro 基本整合 https://www.w3cschool.cn/shiro/c52r1iff.html http://shiro.apache.org/configura ...

  4. Springboot与Mybatis整合

    最近自己用springboot和mybatis做了整合,记录一下: 1.先导入用到的jar包 <dependency> <groupId>org.springframework ...

  5. SpringBoot系列——MyBatis整合

    前言 MyBatis官网:http://www.mybatis.org/mybatis-3/zh/index.html 本文记录springboot与mybatis的整合实例:1.以注解方式:2.手写 ...

  6. SpringBoot与Mybatis整合实例详解

    介绍 从Spring Boot项目名称中的Boot可以看出来,SpringBoot的作用在于创建和启动新的基于Spring框架的项目,它的目的是帮助开发人员很容易的创建出独立运行的产品和产品级别的基于 ...

  7. spring-boot、mybatis整合

    一.MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 X ...

  8. springBoot和MyBatis整合中出现SpringBoot无法启动时处理方式

    在springBoot和Myatis   整合中出现springBoot无法启动   并且报以下错误 Description: Field userMapper in cn.lijun.control ...

  9. springboot+Druid+mybatis整合

    一.添加Druid.MySQL连接池.mybatis依赖 <!--整合Druid--> <dependency> <groupId>com.alibaba</ ...

随机推荐

  1. [转]MEF学习

    MEF学习 :http://www.cnblogs.com/comsokey/p/MEF1.html C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo C#可扩展编程之MEF学习笔记( ...

  2. 【JZOJ3400】旅行

    description 从前有一位旅者,他想要游遍天下所有的景点.这一天他来到了一个神奇的王国:在这片土地上,有n个城市,从1到n进行编号.王国中有m条道路,第i条道路连接着两个城市ai,bi,由于年 ...

  3. 【JZOJ3238】【BZOJ3482】超空间旅行

    description 在遥远的未来,行星之间的食品运输将依靠单向的贸易路线.每条路径直接连接两个行星,且其运输时间是已知的. 贸易商协会打算利用一项最近发现的新技术--超空间旅行,以增加一些新的航线 ...

  4. 使用java代码动态配置与xml文件结合的方式使用mybatis-generator生成代码配置

    1.使用java代码动态配置与xml文件结合的方式使用mybatis-generator生成代码配置 2.上代码:在resources目录下新建:generatorConfiguration.xml文 ...

  5. sqlite3加密

    最近因为工作原因,需要使用sqlite数据库.sqlite数据库小并且使用方便,感觉挺不错的.但有一个不足就是没有对数据库进行加密,不过好的是sqlite预留有加密的接口,我们可以直接调用即可.我也是 ...

  6. Django项目:CMDB(服务器硬件资产自动采集系统)--12--08CMDB采集硬件数据日志记录

    #settings.py # ————————01CMDB获取服务器基本信息———————— import os BASEDIR = os.path.dirname(os.path.dirname(o ...

  7. JS Math.sin() 与 Math.cos() 用法 (含圆上每个点的坐标)

    Math.sin(x)      x 的正玄值.返回值在 -1.0 到 1.0 之间: Math.cos(x)    x 的余弦值.返回的是 -1.0 到 1.0 之间的数: 这两个函数中的X 都是指 ...

  8. 阿里巴巴毕玄解密AIOps:一文读懂阿里巴巴运维体系的前世今生

    [编者按]林昊(毕玄),阿里巴巴研发效能事业部负责人.2007年加入阿里,10年间打造了阿里目前使用最为广泛的核心中间件之一的服务框架:建设了阿里的HBase团队,发展到今天HBase已经是阿里最重要 ...

  9. 1、Zookeeper的功能以及工作原理

    1.ZooKeeper是什么? ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交 ...

  10. font-size:100%

    font-size:100%;设置字体属性为默认大小,是相对于浏览器默认字体大小或继承body设定的字体大小来说的. 例如: h1,h2,h3,h4,h5,h6 {font-size:100%;fon ...